summaryrefslogtreecommitdiffstats
path: root/src/nfc
diff options
context:
space:
mode:
authorMichael Zanetti <michael.zanetti@nokia.com>2011-08-24 14:09:22 +1000
committerRohan McGovern <rohan.mcgovern@nokia.com>2011-08-24 14:10:36 +1000
commit29ba8297443cf76d4f647bde329d62c2a567c709 (patch)
tree88875199053cd88b3b3521c829277f209e815159 /src/nfc
Initial commit.
From qt5connectivity.tar.gz, md5 317c149d6f8c07d09632353188582834
Diffstat (limited to 'src/nfc')
-rw-r--r--src/nfc/checksum_p.h68
-rw-r--r--src/nfc/maemo6/adapter_interface.cpp67
-rw-r--r--src/nfc/maemo6/adapter_interface_p.h192
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.AccessRequestor.xml14
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.Adapter.xml59
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.Device.xml19
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.LLCPRequestor.xml22
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.Manager.xml47
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.NDEFHandler.xml10
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.SecureElement.xml34
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.Tag.xml28
-rw-r--r--src/nfc/maemo6/com.nokia.nfc.Target.xml20
-rw-r--r--src/nfc/maemo6/device_interface.cpp67
-rw-r--r--src/nfc/maemo6/device_interface_p.h122
-rwxr-xr-xsrc/nfc/maemo6/generate8
-rw-r--r--src/nfc/maemo6/socketrequestor.cpp704
-rw-r--r--src/nfc/maemo6/socketrequestor_p.h90
-rw-r--r--src/nfc/maemo6/tag_interface.cpp67
-rw-r--r--src/nfc/maemo6/tag_interface_p.h158
-rw-r--r--src/nfc/maemo6/target_interface.cpp67
-rw-r--r--src/nfc/maemo6/target_interface_p.h133
-rw-r--r--src/nfc/nfc.pro210
-rw-r--r--src/nfc/qdeclarativendefrecord.cpp272
-rw-r--r--src/nfc/qdeclarativendefrecord.h96
-rw-r--r--src/nfc/qllcpserver.cpp203
-rw-r--r--src/nfc/qllcpserver.h86
-rw-r--r--src/nfc/qllcpserver_maemo6_p.cpp198
-rw-r--r--src/nfc/qllcpserver_maemo6_p.h109
-rw-r--r--src/nfc/qllcpserver_p.cpp92
-rw-r--r--src/nfc/qllcpserver_p.h74
-rw-r--r--src/nfc/qllcpserver_simulator_p.cpp88
-rw-r--r--src/nfc/qllcpserver_simulator_p.h71
-rw-r--r--src/nfc/qllcpserver_symbian_p.cpp160
-rw-r--r--src/nfc/qllcpserver_symbian_p.h86
-rw-r--r--src/nfc/qllcpsocket.cpp404
-rw-r--r--src/nfc/qllcpsocket.h131
-rw-r--r--src/nfc/qllcpsocket_maemo6_p.cpp638
-rw-r--r--src/nfc/qllcpsocket_maemo6_p.h143
-rw-r--r--src/nfc/qllcpsocket_p.cpp190
-rw-r--r--src/nfc/qllcpsocket_p.h93
-rw-r--r--src/nfc/qllcpsocket_simulator_p.cpp186
-rw-r--r--src/nfc/qllcpsocket_simulator_p.h91
-rw-r--r--src/nfc/qllcpsocket_symbian_p.cpp409
-rw-r--r--src/nfc/qllcpsocket_symbian_p.h153
-rw-r--r--src/nfc/qllcpstate_symbian_p.cpp551
-rw-r--r--src/nfc/qllcpstate_symbian_p.h171
-rw-r--r--src/nfc/qndeffilter.cpp202
-rw-r--r--src/nfc/qndeffilter.h98
-rw-r--r--src/nfc/qndefmessage.cpp319
-rw-r--r--src/nfc/qndefmessage.h75
-rw-r--r--src/nfc/qndefnfctextrecord.cpp189
-rw-r--r--src/nfc/qndefnfctextrecord.h75
-rw-r--r--src/nfc/qndefnfcurirecord.cpp142
-rw-r--r--src/nfc/qndefnfcurirecord.h66
-rw-r--r--src/nfc/qndefrecord.cpp349
-rw-r--r--src/nfc/qndefrecord.h118
-rw-r--r--src/nfc/qndefrecord_p.h63
-rw-r--r--src/nfc/qnearfieldllcpdevice_symbian.cpp69
-rw-r--r--src/nfc/qnearfieldllcpdevice_symbian_p.h69
-rw-r--r--src/nfc/qnearfieldmanager.cpp554
-rw-r--r--src/nfc/qnearfieldmanager.h116
-rw-r--r--src/nfc/qnearfieldmanager_emulator.cpp102
-rw-r--r--src/nfc/qnearfieldmanager_emulator_p.h76
-rw-r--r--src/nfc/qnearfieldmanager_maemo6.cpp449
-rw-r--r--src/nfc/qnearfieldmanager_maemo6_p.h144
-rw-r--r--src/nfc/qnearfieldmanager_p.h129
-rw-r--r--src/nfc/qnearfieldmanager_simulator.cpp204
-rw-r--r--src/nfc/qnearfieldmanager_simulator_p.h76
-rw-r--r--src/nfc/qnearfieldmanager_symbian.cpp385
-rw-r--r--src/nfc/qnearfieldmanager_symbian_p.h135
-rw-r--r--src/nfc/qnearfieldmanagerimpl_p.cpp61
-rw-r--r--src/nfc/qnearfieldmanagerimpl_p.h54
-rw-r--r--src/nfc/qnearfieldmanagervirtualbase.cpp215
-rw-r--r--src/nfc/qnearfieldmanagervirtualbase_p.h90
-rw-r--r--src/nfc/qnearfieldtagmifare_symbian.cpp98
-rw-r--r--src/nfc/qnearfieldtagmifare_symbian_p.h97
-rw-r--r--src/nfc/qnearfieldtagtype1.cpp735
-rw-r--r--src/nfc/qnearfieldtagtype1.h98
-rw-r--r--src/nfc/qnearfieldtagtype1_symbian.cpp402
-rw-r--r--src/nfc/qnearfieldtagtype1_symbian_p.h104
-rw-r--r--src/nfc/qnearfieldtagtype2.cpp348
-rw-r--r--src/nfc/qnearfieldtagtype2.h87
-rw-r--r--src/nfc/qnearfieldtagtype2_symbian.cpp245
-rw-r--r--src/nfc/qnearfieldtagtype2_symbian_p.h96
-rw-r--r--src/nfc/qnearfieldtagtype3.cpp185
-rw-r--r--src/nfc/qnearfieldtagtype3.h78
-rw-r--r--src/nfc/qnearfieldtagtype3_symbian.cpp504
-rw-r--r--src/nfc/qnearfieldtagtype3_symbian_p.h112
-rw-r--r--src/nfc/qnearfieldtagtype4.cpp161
-rw-r--r--src/nfc/qnearfieldtagtype4.h73
-rw-r--r--src/nfc/qnearfieldtagtype4_symbian.cpp396
-rw-r--r--src/nfc/qnearfieldtagtype4_symbian_p.h104
-rw-r--r--src/nfc/qnearfieldtarget.cpp464
-rw-r--r--src/nfc/qnearfieldtarget.h172
-rw-r--r--src/nfc/qnearfieldtarget_emulator.cpp300
-rw-r--r--src/nfc/qnearfieldtarget_emulator_p.h114
-rw-r--r--src/nfc/qnearfieldtarget_maemo6.cpp176
-rw-r--r--src/nfc/qnearfieldtarget_maemo6_p.h309
-rw-r--r--src/nfc/qnearfieldtarget_p.h62
-rw-r--r--src/nfc/qtlv.cpp528
-rw-r--r--src/nfc/qtlv_p.h124
-rw-r--r--src/nfc/qtnfcversion.h9
-rw-r--r--src/nfc/symbian/debug.h60
-rw-r--r--src/nfc/symbian/llcpserver_symbian.cpp210
-rw-r--r--src/nfc/symbian/llcpserver_symbian.h110
-rw-r--r--src/nfc/symbian/llcpsockettype1_symbian.cpp857
-rw-r--r--src/nfc/symbian/llcpsockettype1_symbian.h305
-rw-r--r--src/nfc/symbian/llcpsockettype2_symbian.cpp986
-rw-r--r--src/nfc/symbian/llcpsockettype2_symbian.h266
-rw-r--r--src/nfc/symbian/nearfieldmanager_symbian.cpp388
-rw-r--r--src/nfc/symbian/nearfieldmanager_symbian.h115
-rw-r--r--src/nfc/symbian/nearfieldndeftarget_symbian.cpp315
-rw-r--r--src/nfc/symbian/nearfieldndeftarget_symbian.h124
-rw-r--r--src/nfc/symbian/nearfieldtag_symbian.cpp181
-rw-r--r--src/nfc/symbian/nearfieldtag_symbian.h94
-rw-r--r--src/nfc/symbian/nearfieldtagasyncrequest_symbian.cpp277
-rw-r--r--src/nfc/symbian/nearfieldtagasyncrequest_symbian.h107
-rw-r--r--src/nfc/symbian/nearfieldtagcommandrequest_symbian.cpp158
-rw-r--r--src/nfc/symbian/nearfieldtagcommandrequest_symbian.h72
-rw-r--r--src/nfc/symbian/nearfieldtagcommandsrequest_symbian.cpp207
-rw-r--r--src/nfc/symbian/nearfieldtagcommandsrequest_symbian.h74
-rw-r--r--src/nfc/symbian/nearfieldtagimpl_symbian.h181
-rw-r--r--src/nfc/symbian/nearfieldtagimplcommon_symbian.cpp596
-rw-r--r--src/nfc/symbian/nearfieldtagimplcommon_symbian.h123
-rw-r--r--src/nfc/symbian/nearfieldtagndefoperationcallback_symbian.h54
-rw-r--r--src/nfc/symbian/nearfieldtagndefrequest_symbian.cpp171
-rw-r--r--src/nfc/symbian/nearfieldtagndefrequest_symbian.h79
-rw-r--r--src/nfc/symbian/nearfieldtagoperationcallback_symbian.h51
-rw-r--r--src/nfc/symbian/nearfieldtargetfactory_symbian.cpp160
-rw-r--r--src/nfc/symbian/nearfieldtargetfactory_symbian.h66
-rw-r--r--src/nfc/symbian/nearfieldutility_symbian.cpp178
-rw-r--r--src/nfc/symbian/nearfieldutility_symbian.h92
-rw-r--r--src/nfc/targetemulator.cpp382
-rw-r--r--src/nfc/targetemulator_p.h107
134 files changed, 24852 insertions, 0 deletions
diff --git a/src/nfc/checksum_p.h b/src/nfc/checksum_p.h
new file mode 100644
index 00000000..48b761b9
--- /dev/null
+++ b/src/nfc/checksum_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CHECKSUM_P_H
+#define CHECKSUM_P_H
+
+// Copied from qbytearray.cpp
+// Modified to initialise the crc with 0x6363 instead of 0xffff and to not invert the final result.
+static const quint16 crc_tbl[16] = {
+ 0x0000, 0x1081, 0x2102, 0x3183,
+ 0x4204, 0x5285, 0x6306, 0x7387,
+ 0x8408, 0x9489, 0xa50a, 0xb58b,
+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
+};
+
+quint16 qNfcChecksum(const char *data, uint len)
+{
+ register quint16 crc = 0x6363;
+ uchar c;
+ const uchar *p = reinterpret_cast<const uchar *>(data);
+ while (len--) {
+ c = *p++;
+ crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
+ c >>= 4;
+ crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
+ }
+ return crc;
+}
+
+#endif // CHECKSUM_P_H
diff --git a/src/nfc/maemo6/adapter_interface.cpp b/src/nfc/maemo6/adapter_interface.cpp
new file mode 100644
index 00000000..bb50f38e
--- /dev/null
+++ b/src/nfc/maemo6/adapter_interface.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -p adapter_interface_p.h:adapter_interface.cpp com.nokia.nfc.Adapter.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "adapter_interface_p.h"
+
+/*
+ * Implementation of interface class ComNokiaNfcAdapterInterface
+ */
+
+ComNokiaNfcAdapterInterface::ComNokiaNfcAdapterInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+ComNokiaNfcAdapterInterface::~ComNokiaNfcAdapterInterface()
+{
+}
+
diff --git a/src/nfc/maemo6/adapter_interface_p.h b/src/nfc/maemo6/adapter_interface_p.h
new file mode 100644
index 00000000..57df898d
--- /dev/null
+++ b/src/nfc/maemo6/adapter_interface_p.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7 and then hand edited
+ * Command line was: qdbusxml2cpp -p adapter_interface_p.h:adapter_interface.cpp com.nokia.nfc.Adapter.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ */
+
+#ifndef ADAPTER_INTERFACE_P_H
+#define ADAPTER_INTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface com.nokia.nfc.Adapter
+ */
+class ComNokiaNfcAdapterInterface: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "com.nokia.nfc.Adapter"; }
+
+public:
+ ComNokiaNfcAdapterInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~ComNokiaNfcAdapterInterface();
+
+ Q_PROPERTY(bool Discovering READ discovering)
+ inline bool discovering() {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return false;
+
+ return reply.value().value(QLatin1String("Discovering")).toBool();
+ }
+
+ Q_PROPERTY(QString State READ state WRITE setState)
+ inline QString state() {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QString();
+
+ return reply.value().value(QLatin1String("State")).toString();
+ }
+
+ inline void setState(const QString &value)
+ { SetProperty(QLatin1String("State"), QDBusVariant(qVariantFromValue(value))); }
+
+ Q_PROPERTY(QStringList TagTechnologies READ tagTechnologies)
+ inline QStringList tagTechnologies()
+ {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QStringList();
+
+ return reply.value().value(QLatin1String("TagTechnologies")).toStringList();
+ }
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<> CancelAccessRequest(const QDBusObjectPath &in0, const QString &in1)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
+ return asyncCallWithArgumentList(QLatin1String("CancelAccessRequest"), argumentList);
+ }
+
+ inline QDBusPendingReply<> CancelHandoverRequest(const QString &in0)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0);
+ return asyncCallWithArgumentList(QLatin1String("CancelHandoverRequest"), argumentList);
+ }
+
+ inline QDBusPendingReply<QVariantMap> GetProperties()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ }
+
+ inline QDBusPendingReply<> RegisterUIAgent(const QDBusObjectPath &in0)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0);
+ return asyncCallWithArgumentList(QLatin1String("RegisterUIAgent"), argumentList);
+ }
+
+ inline QDBusPendingReply<> RequestAccess(const QDBusObjectPath &in0, const QString &in1)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
+ return asyncCallWithArgumentList(QLatin1String("RequestAccess"), argumentList);
+ }
+
+ inline QDBusPendingReply<> RequestHandover(const QDBusObjectPath &in0, const QString &in1, const QString &in2)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2);
+ return asyncCallWithArgumentList(QLatin1String("RequestHandover"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetProperty(const QString &in0, const QDBusVariant &in1)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
+ return asyncCallWithArgumentList(QLatin1String("SetProperty"), argumentList);
+ }
+
+ inline QDBusPendingReply<> UnregisterUIAgent(const QDBusObjectPath &in0)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0);
+ return asyncCallWithArgumentList(QLatin1String("UnregisterUIAgent"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void HandoverCarrierSelected(const QString &in0);
+ void HandoverCompleted(const QString &in0, const QDBusVariant &in1);
+ void HandoverFailed(const QString &in0);
+ void HandoverStarted();
+ void PropertyChanged(const QString &in0, const QDBusVariant &in1);
+ void TargetDetected(const QDBusObjectPath &in0);
+ void TargetLost(const QDBusObjectPath &in0);
+};
+
+namespace com {
+ namespace nokia {
+ namespace nfc {
+ typedef ::ComNokiaNfcAdapterInterface Adapter;
+ }
+ }
+}
+#endif
diff --git a/src/nfc/maemo6/com.nokia.nfc.AccessRequestor.xml b/src/nfc/maemo6/com.nokia.nfc.AccessRequestor.xml
new file mode 100644
index 00000000..655448d2
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.AccessRequestor.xml
@@ -0,0 +1,14 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/foo">
+ <interface name="com.nokia.nfc.AccessRequestor">
+ <method name="AccessFailed">
+ <arg type="o" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ </method>
+ <method name="AccessGranted">
+ <arg type="o" direction="in"/>
+ <arg type="s" direction="in"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/nfc/maemo6/com.nokia.nfc.Adapter.xml b/src/nfc/maemo6/com.nokia.nfc.Adapter.xml
new file mode 100644
index 00000000..3e3d3c85
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.Adapter.xml
@@ -0,0 +1,59 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/com/nokia/nfc/0/nfc0">
+ <interface name="com.nokia.nfc.Adapter">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
+ </method>
+ <method name="SetProperty">
+ <arg type="s" direction="in"/>
+ <arg type="v" direction="in"/>
+ </method>
+ <method name="RequestHandover">
+ <arg type="o" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ </method>
+ <method name="CancelHandoverRequest">
+ <arg type="s" direction="in"/>
+ </method>
+ <method name="RequestAccess">
+ <arg type="o" direction="in"/>
+ <arg type="s" direction="in"/>
+ </method>
+ <method name="CancelAccessRequest">
+ <arg type="o" direction="in"/>
+ <arg type="s" direction="in"/>
+ </method>
+ <method name="RegisterUIAgent">
+ <arg type="o" direction="in"/>
+ </method>
+ <method name="UnregisterUIAgent">
+ <arg type="o" direction="in"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ <signal name="TargetDetected">
+ <arg type="o"/>
+ </signal>
+ <signal name="TargetLost">
+ <arg type="o"/>
+ </signal>
+ <signal name="HandoverStarted"/>
+ <signal name="HandoverCarrierSelected">
+ <arg type="s"/>
+ </signal>
+ <signal name="HandoverCompleted">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ <signal name="HandoverFailed">
+ <arg type="s"/>
+ </signal>
+ <property name="State" type="s" access="readwrite"/>
+ <property name="Discovering" type="b" access="read"/>
+ <property name="TagTechnologies" type="as" access="read"/>
+ </interface>
+</node>
diff --git a/src/nfc/maemo6/com.nokia.nfc.Device.xml b/src/nfc/maemo6/com.nokia.nfc.Device.xml
new file mode 100644
index 00000000..17acc5d0
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.Device.xml
@@ -0,0 +1,19 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/com/nokia/nfc/0/nfc0/target_DE_AD_BE_EF">
+ <interface name="com.nokia.nfc.Device">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
+ </method>
+ <method name="SetProperty">
+ <arg type="s" direction="in"/>
+ <arg type="v" direction="in"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ <property name="UID" type="s" access="read"/>
+ </interface>
+</node>
+
diff --git a/src/nfc/maemo6/com.nokia.nfc.LLCPRequestor.xml b/src/nfc/maemo6/com.nokia.nfc.LLCPRequestor.xml
new file mode 100644
index 00000000..cf4f625a
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.LLCPRequestor.xml
@@ -0,0 +1,22 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/foo">
+ <interface name="com.nokia.nfc.LLCPRequestor">
+ <method name="Accept">
+ <arg type="v" direction="in"/>
+ <arg type="v" direction="in"/>
+ <arg type="h" direction="in"/>
+ <arg type="a{sv}" direction="in"/>
+ </method>
+ <method name="Connect">
+ <arg type="v" direction="in"/>
+ <arg type="v" direction="in"/>
+ <arg type="h" direction="in"/>
+ <arg type="a{sv}" direction="in"/>
+ </method>
+ <method name="Socket">
+ <arg type="v" direction="in"/>
+ <arg type="h" direction="in"/>
+ <arg type="a{sv}" direction="in"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/nfc/maemo6/com.nokia.nfc.Manager.xml b/src/nfc/maemo6/com.nokia.nfc.Manager.xml
new file mode 100644
index 00000000..cdc8fae8
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.Manager.xml
@@ -0,0 +1,47 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/">
+ <interface name="com.nokia.nfc.Manager">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
+ </method>
+ <method name="SetProperty">
+ <arg type="s" direction="in"/>
+ <arg type="v" direction="in"/>
+ </method>
+ <method name="ListAdapters">
+ <arg type="ao" direction="out"/>
+ </method>
+ <method name="FindAdapter">
+ <arg type="s" direction="in"/>
+ <arg type="o" direction="out"/>
+ </method>
+ <method name="DefaultAdapter">
+ <arg type="o" direction="out"/>
+ </method>
+ <method name="RegisterNDEFHandler">
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="o" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ </method>
+ <method name="UnregisterNDEFHandler">
+ <arg type="s" direction="in"/>
+ <arg type="s" direction="in"/>
+ <arg type="o" direction="in"/>
+ </method>
+ <signal name="AdapterAdded">
+ <arg type="o"/>
+ </signal>
+ <signal name="AdapterRemoved">
+ <arg type="o"/>
+ </signal>
+ <signal name="DefaultAdapterChanged">
+ <arg type="o"/>
+ </signal>
+ <property name="LogLevel" type="s" access="readwrite"/>
+ </interface>
+</node>
+
diff --git a/src/nfc/maemo6/com.nokia.nfc.NDEFHandler.xml b/src/nfc/maemo6/com.nokia.nfc.NDEFHandler.xml
new file mode 100644
index 00000000..8b4fdd45
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.NDEFHandler.xml
@@ -0,0 +1,10 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/foo">
+ <interface name="com.nokia.nfc.NDEFHandler">
+ <method name="NDEFData">
+ <arg type="o" direction="in"/>
+ <arg type="ay" direction="in"/>
+ </method>
+ </interface>
+</node>
+
diff --git a/src/nfc/maemo6/com.nokia.nfc.SecureElement.xml b/src/nfc/maemo6/com.nokia.nfc.SecureElement.xml
new file mode 100644
index 00000000..702f3b2a
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.SecureElement.xml
@@ -0,0 +1,34 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/com/nokia/nfc/0/nfc0/se0">
+ <interface name="com.nokia.nfc.SecureElement">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
+ </method>
+ <method name="RequestAccess"/>
+ <method name="ReleaseAccess"/>
+ <method name="Activate"/>
+ <method name="Deactivate"/>
+ <method name="SetActivationLevel">
+ <arg type="v" direction="in"/>
+ </method>
+ <method name="RawRequest">
+ <arg type="ay" direction="in"/>
+ <arg type="ay" direction="out"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ <signal name="TransactionStarted">
+ <arg type="s"/>
+ </signal>
+ <signal name="TransactionEnded">
+ <arg type="s"/>
+ <arg type="s"/>
+ </signal>
+ <property name="State" type="s" access="read"/>
+ <property name="ActivationLevel" type="s" access="read"/>
+ </interface>
+</node>
+
diff --git a/src/nfc/maemo6/com.nokia.nfc.Tag.xml b/src/nfc/maemo6/com.nokia.nfc.Tag.xml
new file mode 100644
index 00000000..4d24850f
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.Tag.xml
@@ -0,0 +1,28 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/com/nokia/nfc/0/nfc0/target_DE_AD_BE_EF">
+ <interface name="com.nokia.nfc.Tag">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
+ </method>
+ <method name="SetProperty">
+ <arg type="s" direction="in"/>
+ <arg type="v" direction="in"/>
+ </method>
+ <method name="ReadNDEFData">
+ <arg type="aay" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QList&lt;QByteArray&gt;"/>
+ </method>
+ <method name="WriteNDEFData">
+ <arg type="aay" direction="in"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QList&lt;QByteArray&gt;"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ <property name="UID" type="s" access="read"/>
+ <property name="Technology" type="s" access="read"/>
+ </interface>
+</node>
+
diff --git a/src/nfc/maemo6/com.nokia.nfc.Target.xml b/src/nfc/maemo6/com.nokia.nfc.Target.xml
new file mode 100644
index 00000000..a5fa2308
--- /dev/null
+++ b/src/nfc/maemo6/com.nokia.nfc.Target.xml
@@ -0,0 +1,20 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/com/nokia/nfc/0/nfc0/target_DE_AD_BE_EF">
+ <interface name="com.nokia.nfc.Target">
+ <method name="GetProperties">
+ <arg type="a{sv}" direction="out"/>
+ <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
+ </method>
+ <method name="SetProperty">
+ <arg type="s" direction="in"/>
+ <arg type="v" direction="in"/>
+ </method>
+ <signal name="PropertyChanged">
+ <arg type="s"/>
+ <arg type="v"/>
+ </signal>
+ <property name="Type" type="s" access="read"/>
+ <property name="State" type="s" access="read"/>
+ </interface>
+</node>
+
diff --git a/src/nfc/maemo6/device_interface.cpp b/src/nfc/maemo6/device_interface.cpp
new file mode 100644
index 00000000..69b2c930
--- /dev/null
+++ b/src/nfc/maemo6/device_interface.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -p device_interface_p.h:device_interface.cpp com.nokia.nfc.Device.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "device_interface_p.h"
+
+/*
+ * Implementation of interface class ComNokiaNfcDeviceInterface
+ */
+
+ComNokiaNfcDeviceInterface::ComNokiaNfcDeviceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+ComNokiaNfcDeviceInterface::~ComNokiaNfcDeviceInterface()
+{
+}
+
diff --git a/src/nfc/maemo6/device_interface_p.h b/src/nfc/maemo6/device_interface_p.h
new file mode 100644
index 00000000..ff2d5604
--- /dev/null
+++ b/src/nfc/maemo6/device_interface_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7 and then hand edited
+ * Command line was: qdbusxml2cpp -p device_interface_p.h:device_interface.cpp com.nokia.nfc.Device.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ */
+
+#ifndef DEVICE_INTERFACE_P_H
+#define DEVICE_INTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface com.nokia.nfc.Device
+ */
+class ComNokiaNfcDeviceInterface: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "com.nokia.nfc.Device"; }
+
+public:
+ ComNokiaNfcDeviceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~ComNokiaNfcDeviceInterface();
+
+ Q_PROPERTY(QString UID READ uID)
+ inline QString uID() {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QString();
+
+ return reply.value().value(QLatin1String("UID")).toString();
+ }
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<QVariantMap> GetProperties()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetProperty(const QString &in0, const QDBusVariant &in1)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
+ return asyncCallWithArgumentList(QLatin1String("SetProperty"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void PropertyChanged(const QString &in0, const QDBusVariant &in1);
+};
+
+namespace com {
+ namespace nokia {
+ namespace nfc {
+ typedef ::ComNokiaNfcDeviceInterface Device;
+ }
+ }
+}
+#endif
diff --git a/src/nfc/maemo6/generate b/src/nfc/maemo6/generate
new file mode 100755
index 00000000..fa7260d5
--- /dev/null
+++ b/src/nfc/maemo6/generate
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+qdbusxml2cpp -p adapter_interface_p.h:adapter_interface.cpp com.nokia.nfc.Adapter.xml
+
+qdbusxml2cpp -p target_interface_p.h:target_interface.cpp com.nokia.nfc.Target.xml
+qdbusxml2cpp -p tag_interface_p.h:tag_interface.cpp com.nokia.nfc.Tag.xml
+qdbusxml2cpp -p device_interface_p.h:device_interface.cpp com.nokia.nfc.Device.xml
+
diff --git a/src/nfc/maemo6/socketrequestor.cpp b/src/nfc/maemo6/socketrequestor.cpp
new file mode 100644
index 00000000..b7595bc8
--- /dev/null
+++ b/src/nfc/maemo6/socketrequestor.cpp
@@ -0,0 +1,704 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "socketrequestor_p.h"
+
+#include <QtCore/QMutex>
+#include <QtCore/QHash>
+#include <QtCore/QSocketNotifier>
+#include <QtCore/QStringList>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QCoreApplication>
+#include <QtDBus/QDBusObjectPath>
+
+#include <dbus/dbus.h>
+
+#include <sys/select.h>
+#include <errno.h>
+
+struct WatchNotifier
+{
+ DBusWatch *watch;
+ QSocketNotifier *readNotifier;
+ QSocketNotifier *writeNotifier;
+};
+
+static QVariant getVariantFromDBusMessage(DBusMessageIter *iter)
+{
+ dbus_bool_t bool_data;
+ dbus_int32_t int32_data;
+ dbus_uint32_t uint32_data;
+ dbus_int64_t int64_data;
+ dbus_uint64_t uint64_data;
+ char *str_data;
+ char char_data;
+ int argtype = dbus_message_iter_get_arg_type(iter);
+
+ switch (argtype) {
+ case DBUS_TYPE_BOOLEAN: {
+ dbus_message_iter_get_basic(iter, &bool_data);
+ QVariant variant((bool)bool_data);
+ return variant;
+ }
+ case DBUS_TYPE_ARRAY: {
+ // Handle all arrays here
+ int elem_type = dbus_message_iter_get_element_type(iter);
+ DBusMessageIter array_iter;
+
+ dbus_message_iter_recurse(iter, &array_iter);
+
+ if (elem_type == DBUS_TYPE_BYTE) {
+ QByteArray byte_array;
+ do {
+ dbus_message_iter_get_basic(&array_iter, &char_data);
+ byte_array.append(char_data);
+ } while (dbus_message_iter_next(&array_iter));
+ QVariant variant(byte_array);
+ return variant;
+ } else if (elem_type == DBUS_TYPE_STRING) {
+ QStringList str_list;
+ do {
+ dbus_message_iter_get_basic(&array_iter, &str_data);
+ str_list.append(str_data);
+ } while (dbus_message_iter_next(&array_iter));
+ QVariant variant(str_list);
+ return variant;
+ } else {
+ QVariantList variantList;
+ do {
+ variantList << getVariantFromDBusMessage(&array_iter);
+ } while (dbus_message_iter_next(&array_iter));
+ QVariant variant(variantList);
+ return variant;
+ }
+ break;
+ }
+ case DBUS_TYPE_BYTE: {
+ dbus_message_iter_get_basic(iter, &char_data);
+ QChar ch(char_data);
+ QVariant variant(ch);
+ return variant;
+ }
+ case DBUS_TYPE_INT32: {
+ dbus_message_iter_get_basic(iter, &int32_data);
+ QVariant variant((int)int32_data);
+ return variant;
+ }
+ case DBUS_TYPE_UINT32: {
+ dbus_message_iter_get_basic(iter, &uint32_data);
+ QVariant variant((uint)uint32_data);
+ return variant;
+ }
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_STRING: {
+ dbus_message_iter_get_basic(iter, &str_data);
+ QString str(str_data);
+ QVariant variant(str);
+ return variant;
+ }
+ case DBUS_TYPE_INT64: {
+ dbus_message_iter_get_basic(iter, &int64_data);
+ QVariant variant((qlonglong)int64_data);
+ return variant;
+ }
+ case DBUS_TYPE_UINT64: {
+ dbus_message_iter_get_basic(iter, &uint64_data);
+ QVariant variant((qulonglong)uint64_data);
+ return variant;
+ }
+ case DBUS_TYPE_DICT_ENTRY:
+ case DBUS_TYPE_STRUCT: {
+ // Handle all structs here
+ DBusMessageIter struct_iter;
+ dbus_message_iter_recurse(iter, &struct_iter);
+
+ QVariantList variantList;
+ do {
+ variantList << getVariantFromDBusMessage(&struct_iter);
+ } while (dbus_message_iter_next(&struct_iter));
+ QVariant variant(variantList);
+ return variant;
+ }
+ case DBUS_TYPE_VARIANT: {
+ DBusMessageIter variant_iter;
+ dbus_message_iter_recurse(iter, &variant_iter);
+
+ return getVariantFromDBusMessage(&variant_iter);
+ }
+ case DBUS_TYPE_UNIX_FD: {
+ dbus_message_iter_get_basic(iter, &uint32_data);
+ QVariant variant((uint)uint32_data);
+ return variant;
+ }
+
+ default:
+ qWarning("Unsupported DBUS type: %d\n", argtype);
+ }
+
+ return QVariant();
+}
+
+class SocketRequestorPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ SocketRequestorPrivate();
+ ~SocketRequestorPrivate();
+
+ DBusHandlerResult messageFilter(DBusConnection *connection, DBusMessage *message);
+ void addWatch(DBusWatch *watch);
+
+ void registerObject(const QString &path, SocketRequestor *object);
+ void unregisterObject(const QString &path);
+
+ Q_INVOKABLE void sendRequestAccess(const QString &adaptor, const QString &path,
+ const QString &kind);
+ Q_INVOKABLE void sendCancelAccessRequest(const QString &adaptor, const QString &path,
+ const QString &kind);
+
+ bool waitForDBusSignal(int msecs);
+
+private:
+ bool parseAccessFailed(DBusMessage *message, SocketRequestor *socketRequestor);
+ bool parseAccessGranted(DBusMessage *message, SocketRequestor *socketRequestor);
+ bool parseAcceptConnect(DBusMessage *message, SocketRequestor *socketRequestor,
+ const char *member);
+ bool parseSocket(DBusMessage *message, SocketRequestor *socketRequestor, const char *member);
+ bool parseErrorDenied(DBusMessage *message, SocketRequestor *socketRequestor);
+
+private slots:
+ void socketRead();
+ void socketWrite();
+
+private:
+ QMutex m_mutex;
+ DBusConnection *m_dbusConnection;
+ QHash<QString, SocketRequestor *> m_dbusObjects;
+ QMap<quint32, SocketRequestor *> m_pendingCalls;
+ QList<WatchNotifier> m_watchNotifiers;
+};
+
+Q_GLOBAL_STATIC(SocketRequestorPrivate, socketRequestorPrivate)
+
+static DBusHandlerResult dbusFilter(DBusConnection *connection, DBusMessage *message,
+ void *userData)
+{
+ SocketRequestorPrivate *s = static_cast<SocketRequestorPrivate *>(userData);
+ return s->messageFilter(connection, message);
+}
+
+static dbus_bool_t dbusWatch(DBusWatch *watch, void *data)
+{
+ SocketRequestorPrivate *s = static_cast<SocketRequestorPrivate *>(data);
+ s->addWatch(watch);
+
+ return true;
+}
+
+SocketRequestorPrivate::SocketRequestorPrivate()
+{
+ DBusError error;
+ dbus_error_init(&error);
+ m_dbusConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+ dbus_connection_add_filter(m_dbusConnection, &dbusFilter, this, 0);
+ dbus_connection_set_watch_functions(m_dbusConnection, dbusWatch, 0, 0, this, 0);
+ dbus_error_free(&error);
+}
+
+SocketRequestorPrivate::~SocketRequestorPrivate()
+{
+ dbus_connection_close(m_dbusConnection);
+ dbus_connection_unref(m_dbusConnection);
+}
+
+DBusHandlerResult SocketRequestorPrivate::messageFilter(DBusConnection *connection,
+ DBusMessage *message)
+{
+ QMutexLocker locker(&m_mutex);
+
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers)
+ watchNotifier.writeNotifier->setEnabled(true);
+
+ if (connection != m_dbusConnection)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ SocketRequestor *socketRequestor;
+ const QString path = QString::fromUtf8(dbus_message_get_path(message));
+ quint32 serial = dbus_message_get_reply_serial(message);
+ if (!path.isEmpty() && serial == 0)
+ socketRequestor = m_dbusObjects.value(path);
+ else if (path.isEmpty() && serial != 0)
+ socketRequestor = m_pendingCalls.take(serial);
+ else
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ enum {
+ NotHandled,
+ Handled,
+ HandledSendReply
+ } handled;
+
+ if (dbus_message_is_method_call(message, "com.nokia.nfc.AccessRequestor", "AccessFailed"))
+ handled = parseAccessFailed(message, socketRequestor) ? HandledSendReply : NotHandled;
+ else if (dbus_message_is_method_call(message, "com.nokia.nfc.AccessRequestor", "AccessGranted"))
+ handled = parseAccessGranted(message, socketRequestor) ? HandledSendReply : NotHandled;
+ else if (dbus_message_is_method_call(message, "com.nokia.nfc.LLCPRequestor", "Accept"))
+ handled = parseAcceptConnect(message, socketRequestor, "accept") ? HandledSendReply : NotHandled;
+ else if (dbus_message_is_method_call(message, "com.nokia.nfc.LLCPRequestor", "Connect"))
+ handled = parseAcceptConnect(message, socketRequestor, "connect") ? HandledSendReply : NotHandled;
+ else if (dbus_message_is_method_call(message, "com.nokia.nfc.LLCPRequestor", "Socket"))
+ handled = parseSocket(message, socketRequestor, "socket") ? HandledSendReply : NotHandled;
+ else if (dbus_message_is_error(message, "com.nokia.nfc.Error.Denied"))
+ handled = parseErrorDenied(message, socketRequestor) ? Handled : NotHandled;
+ else
+ handled = NotHandled;
+
+ if (handled == NotHandled)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (handled == HandledSendReply) {
+ DBusMessage *reply = dbus_message_new_method_return(message);
+ quint32 serial;
+ dbus_connection_send(connection, reply, &serial);
+ }
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+bool SocketRequestorPrivate::parseErrorDenied(DBusMessage *message,
+ SocketRequestor *socketRequestor)
+{
+ Q_UNUSED(message);
+
+ QMetaObject::invokeMethod(socketRequestor, "accessFailed",
+ Q_ARG(QDBusObjectPath, QDBusObjectPath()),
+ Q_ARG(QString, QLatin1String("")),
+ Q_ARG(QString, QLatin1String("Access denied")));
+ return true;
+}
+
+bool SocketRequestorPrivate::parseAccessFailed(DBusMessage *message,
+ SocketRequestor *socketRequestor)
+{
+ Q_UNUSED(message);
+
+ // m_mutex is locked in messageFilter()
+
+ DBusMessageIter args;
+
+ if (!dbus_message_iter_init(message, &args))
+ return false;
+
+ // read DBus Object Path
+ QVariant objectPath = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read DBus kind string
+ QVariant kind = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read DBus error string
+ QVariant errorString = getVariantFromDBusMessage(&args);
+
+ QMetaObject::invokeMethod(socketRequestor, "accessFailed",
+ Q_ARG(QDBusObjectPath, QDBusObjectPath(objectPath.toString())),
+ Q_ARG(QString, kind.toString()),
+ Q_ARG(QString, errorString.toString()));
+ return true;
+}
+
+bool SocketRequestorPrivate::parseAccessGranted(DBusMessage *message,
+ SocketRequestor *socketRequestor)
+{
+ Q_UNUSED(message);
+
+ // m_mutex is locked in messageFilter()
+
+ DBusMessageIter args;
+
+ if (!dbus_message_iter_init(message, &args))
+ return false;
+
+ // read DBus Object Path
+ QVariant objectPath = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read access kind
+ QVariant kind = getVariantFromDBusMessage(&args);
+
+ QMetaObject::invokeMethod(socketRequestor, "accessGranted",
+ Q_ARG(QDBusObjectPath, QDBusObjectPath(objectPath.toString())),
+ Q_ARG(QString, kind.toString()));
+ return true;
+}
+
+bool SocketRequestorPrivate::parseAcceptConnect(DBusMessage *message,
+ SocketRequestor *socketRequestor,
+ const char *member)
+{
+ // m_mutex is locked in messageFilter()
+
+ DBusMessageIter args;
+
+ if (!dbus_message_iter_init(message, &args))
+ return false;
+
+ // read DBus Variant (lsap)
+ QVariant lsap = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+ // read DBus Variant (rsap)
+ QVariant rsap = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read socket fd
+ QVariant fd = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read DBus a{sv} into QVariantMap
+ QVariant prop = getVariantFromDBusMessage(&args);
+ QVariantMap properties;
+ foreach (const QVariant &v, prop.toList()) {
+ QVariantList vl = v.toList();
+ if (vl.length() != 2)
+ continue;
+
+ properties.insert(vl.first().toString(), vl.at(1));
+ }
+
+ QMetaObject::invokeMethod(socketRequestor, member, Q_ARG(QDBusVariant, QDBusVariant(lsap)),
+ Q_ARG(QDBusVariant, QDBusVariant(rsap)),
+ Q_ARG(int, fd.toInt()), Q_ARG(QVariantMap, properties));
+
+ return true;
+}
+
+bool SocketRequestorPrivate::parseSocket(DBusMessage *message, SocketRequestor *socketRequestor,
+ const char *member)
+{
+ // m_mutex is locked in messageFilter()
+
+ DBusMessageIter args;
+
+ if (!dbus_message_iter_init(message, &args))
+ return false;
+
+ // read DBus Variant (lsap)
+ QVariant lsap = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read socket fd
+ QVariant fd = getVariantFromDBusMessage(&args);
+
+ if (!dbus_message_iter_next(&args))
+ return false;
+
+ // read DBus a{sv} into QVariantMap
+ QVariant prop = getVariantFromDBusMessage(&args);
+ QVariantMap properties;
+ foreach (const QVariant &v, prop.toList()) {
+ QVariantList vl = v.toList();
+ if (vl.length() != 2)
+ continue;
+
+ properties.insert(vl.first().toString(), vl.at(1));
+ }
+
+ QMetaObject::invokeMethod(socketRequestor, member, Q_ARG(QDBusVariant, QDBusVariant(lsap)),
+ Q_ARG(int, fd.toInt()), Q_ARG(QVariantMap, properties));
+
+ return true;
+}
+
+void SocketRequestorPrivate::addWatch(DBusWatch *watch)
+{
+ QMutexLocker locker(&m_mutex);
+
+ int fd = dbus_watch_get_unix_fd(watch);
+
+ WatchNotifier watchNotifier;
+ watchNotifier.watch = watch;
+
+ watchNotifier.readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
+ connect(watchNotifier.readNotifier, SIGNAL(activated(int)), this, SLOT(socketRead()));
+ watchNotifier.writeNotifier = new QSocketNotifier(fd, QSocketNotifier::Write, this);
+ connect(watchNotifier.writeNotifier, SIGNAL(activated(int)), this, SLOT(socketWrite()));
+
+ m_watchNotifiers.append(watchNotifier);
+}
+
+void SocketRequestorPrivate::socketRead()
+{
+ QMutexLocker locker(&m_mutex);
+
+ QList<DBusWatch *> pendingWatches;
+
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers) {
+ if (watchNotifier.readNotifier != sender())
+ continue;
+
+ pendingWatches.append(watchNotifier.watch);
+ }
+
+ DBusConnection *connection = m_dbusConnection;
+ locker.unlock();
+
+ foreach (DBusWatch *watch, pendingWatches)
+ dbus_watch_handle(watch, DBUS_WATCH_READABLE);
+
+ while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);
+}
+
+void SocketRequestorPrivate::socketWrite()
+{
+ QMutexLocker locker(&m_mutex);
+
+ QList<DBusWatch *> pendingWatches;
+
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers) {
+ if (watchNotifier.writeNotifier != sender())
+ continue;
+
+ watchNotifier.writeNotifier->setEnabled(false);
+ pendingWatches.append(watchNotifier.watch);
+ }
+
+ locker.unlock();
+
+ foreach (DBusWatch *watch, pendingWatches)
+ dbus_watch_handle(watch, DBUS_WATCH_WRITABLE);
+}
+
+void SocketRequestorPrivate::registerObject(const QString &path, SocketRequestor *object)
+{
+ QMutexLocker locker(&m_mutex);
+
+ m_dbusObjects.insert(path, object);
+}
+
+void SocketRequestorPrivate::unregisterObject(const QString &path)
+{
+ QMutexLocker locker(&m_mutex);
+
+ m_dbusObjects.remove(path);
+}
+
+void SocketRequestorPrivate::sendRequestAccess(const QString &adaptor, const QString &path,
+ const QString &kind)
+{
+ QMutexLocker locker(&m_mutex);
+
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers)
+ watchNotifier.writeNotifier->setEnabled(true);
+
+ DBusMessage *message;
+ DBusMessageIter args;
+
+ message = dbus_message_new_method_call("com.nokia.nfc", adaptor.toLocal8Bit(),
+ "com.nokia.nfc.Adapter", "RequestAccess");
+
+ if (!message)
+ return;
+
+ dbus_message_iter_init_append(message, &args);
+ const QByteArray p = path.toUtf8();
+ const char *pData = p.constData();
+ if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &pData)) {
+ dbus_message_unref(message);
+ return;
+ }
+
+ const QByteArray k = kind.toUtf8();
+ const char *kData = k.constData();
+ if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &kData)) {
+ dbus_message_unref(message);
+ return;
+ }
+
+ quint32 serial;
+ dbus_connection_send(m_dbusConnection, message, &serial);
+
+ dbus_message_unref(message);
+
+ m_pendingCalls.insert(serial, m_dbusObjects.value(path));
+}
+
+void SocketRequestorPrivate::sendCancelAccessRequest(const QString &adaptor, const QString &path,
+ const QString &kind)
+{
+ QMutexLocker locker(&m_mutex);
+
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers)
+ watchNotifier.writeNotifier->setEnabled(true);
+
+ DBusMessage *message;
+ DBusMessageIter args;
+
+ message = dbus_message_new_method_call("com.nokia.nfc", adaptor.toLocal8Bit(),
+ "com.nokia.nfc.Adapter", "CancelAccessRequest");
+
+ if (!message)
+ return;
+
+ dbus_message_iter_init_append(message, &args);
+ const QByteArray p = path.toUtf8();
+ const char *pData = p.constData();
+ if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &pData)) {
+ dbus_message_unref(message);
+ return;
+ }
+
+ const QByteArray k = kind.toUtf8();
+ const char *kData = k.constData();
+ if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &kData)) {
+ dbus_message_unref(message);
+ return;
+ }
+
+ quint32 serial;
+ dbus_connection_send(m_dbusConnection, message, &serial);
+
+ dbus_message_unref(message);
+}
+
+bool SocketRequestorPrivate::waitForDBusSignal(int msecs)
+{
+ dbus_connection_flush(m_dbusConnection);
+
+ fd_set rfds;
+ FD_ZERO(&rfds);
+
+ int nfds = -1;
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers) {
+ FD_SET(watchNotifier.readNotifier->socket(), &rfds);
+ nfds = qMax(nfds, watchNotifier.readNotifier->socket());
+ }
+
+ timeval timeout;
+ timeout.tv_sec = msecs / 1000;
+ timeout.tv_usec = (msecs % 1000) * 1000;
+
+ // timeout can not be 0 or else select will return an error
+ if (msecs == 0)
+ timeout.tv_usec = 1000;
+
+ int result = -1;
+ // on Linux timeout will be updated by select, but _not_ on other systems
+ result = ::select(nfds + 1, &rfds, 0, 0, &timeout);
+ if (result == -1 && errno != EINTR)
+ return false;
+
+ foreach (const WatchNotifier &watchNotifier, m_watchNotifiers) {
+ if (FD_ISSET(watchNotifier.readNotifier->socket(), &rfds)) {
+ QMetaObject::invokeMethod(watchNotifier.readNotifier, "activated",
+ Q_ARG(int, watchNotifier.readNotifier->socket()));
+ }
+ }
+
+ return true;
+}
+
+
+SocketRequestor::SocketRequestor(const QString &adaptor, QObject *parent)
+: QObject(parent), m_adaptor(adaptor)
+{
+
+
+}
+
+SocketRequestor::~SocketRequestor()
+{
+}
+
+void SocketRequestor::requestAccess(const QString &path, const QString &kind)
+{
+ SocketRequestorPrivate *s = socketRequestorPrivate();
+
+ s->registerObject(path, this);
+
+ QMetaObject::invokeMethod(s, "sendRequestAccess", Qt::QueuedConnection,
+ Q_ARG(QString, m_adaptor), Q_ARG(QString, path),
+ Q_ARG(QString, kind));
+}
+
+void SocketRequestor::cancelAccessRequest(const QString &path, const QString &kind)
+{
+ SocketRequestorPrivate *s = socketRequestorPrivate();
+
+ s->unregisterObject(path);
+
+ QMetaObject::invokeMethod(s, "sendCancelAccessRequest", Qt::QueuedConnection,
+ Q_ARG(QString, m_adaptor), Q_ARG(QString, path),
+ Q_ARG(QString, kind));
+}
+
+bool SocketRequestor::waitForDBusSignal(int msecs)
+{
+ SocketRequestorPrivate *s = socketRequestorPrivate();
+
+ // Send queued method calls, i.e. requestAccess() and cancelAccessRequest().
+ QCoreApplication::sendPostedEvents(s, QEvent::MetaCall);
+
+ // Wait for DBus signal.
+ bool result = socketRequestorPrivate()->waitForDBusSignal(msecs);
+
+ // Send queued method calls, i.e. those from DBus.
+ QCoreApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+ return result;
+}
+
+#include <moc_socketrequestor_p.cpp>
+#include <socketrequestor.moc>
diff --git a/src/nfc/maemo6/socketrequestor_p.h b/src/nfc/maemo6/socketrequestor_p.h
new file mode 100644
index 00000000..25c46865
--- /dev/null
+++ b/src/nfc/maemo6/socketrequestor_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ The private API defined in this file is temporary. It should be removed when Qt can handle
+ passing unix file descriptors over DBus. Most likely in Qt 4.8.
+*/
+
+#ifndef SOCKETREQUESTOR_P_H
+#define SOCKETREQUESTOR_P_H
+
+#include <qconnectivityglobal.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QVariantMap>
+
+QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
+QT_FORWARD_DECLARE_CLASS(QDBusVariant)
+
+class DBusConnection;
+
+QT_BEGIN_HEADER
+
+class SocketRequestor : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit SocketRequestor(const QString &adaptor, QObject *parent = 0);
+ ~SocketRequestor();
+
+ void requestAccess(const QString &path, const QString &kind);
+ void cancelAccessRequest(const QString &path, const QString &kind);
+
+ bool waitForDBusSignal(int msecs);
+
+signals:
+ void accessFailed(const QDBusObjectPath &targetPath, const QString &kind,
+ const QString &error);
+ void accessGranted(const QDBusObjectPath &targetPath, const QString &accessKind);
+
+ void accept(const QDBusVariant &lsap, const QDBusVariant &rsap, int fd, const QVariantMap &properties);
+ void connect(const QDBusVariant &lsap, const QDBusVariant &rsap, int fd, const QVariantMap &properties);
+ void socket(const QDBusVariant &lsap, int fd, const QVariantMap &properties);
+
+private:
+ const QString m_adaptor;
+};
+
+QT_END_HEADER
+
+#endif // SOCKETREQUESTOR_P_H
diff --git a/src/nfc/maemo6/tag_interface.cpp b/src/nfc/maemo6/tag_interface.cpp
new file mode 100644
index 00000000..61f3b05c
--- /dev/null
+++ b/src/nfc/maemo6/tag_interface.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -p tag_interface_p.h:tag_interface.cpp com.nokia.nfc.Tag.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "tag_interface_p.h"
+
+/*
+ * Implementation of interface class ComNokiaNfcTagInterface
+ */
+
+ComNokiaNfcTagInterface::ComNokiaNfcTagInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+ComNokiaNfcTagInterface::~ComNokiaNfcTagInterface()
+{
+}
+
diff --git a/src/nfc/maemo6/tag_interface_p.h b/src/nfc/maemo6/tag_interface_p.h
new file mode 100644
index 00000000..f7bdec57
--- /dev/null
+++ b/src/nfc/maemo6/tag_interface_p.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7 and then hand edited
+ * Command line was: qdbusxml2cpp -p tag_interface_p.h:tag_interface.cpp com.nokia.nfc.Tag.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ */
+
+#ifndef TAG_INTERFACE_P_H
+#define TAG_INTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+Q_DECLARE_METATYPE(QList<QByteArray>)
+
+/*
+ * Proxy class for interface com.nokia.nfc.Tag
+ */
+class ComNokiaNfcTagInterface: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "com.nokia.nfc.Tag"; }
+
+public:
+ ComNokiaNfcTagInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~ComNokiaNfcTagInterface();
+
+ Q_PROPERTY(uint Size READ size)
+ inline uint size()
+ {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return 0;
+
+ return reply.value().value(QLatin1String("Size")).toUInt();
+ }
+
+ Q_PROPERTY(QString Technology READ technology)
+ inline QString technology()
+ {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QString();
+
+ return reply.value().value(QLatin1String("Technology")).toString();
+ }
+
+ Q_PROPERTY(QString UID READ uID)
+ inline QString uID()
+ {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QString();
+
+ return reply.value().value(QLatin1String("UID")).toString();
+ }
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<QVariantMap> GetProperties()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ }
+
+ inline QDBusPendingReply<QList<QByteArray> > ReadNDEFData()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("ReadNDEFData"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetProperty(const QString &in0, const QDBusVariant &in1)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
+ return asyncCallWithArgumentList(QLatin1String("SetProperty"), argumentList);
+ }
+
+ inline QDBusPendingReply<> WriteNDEFData(const QList<QByteArray> &in0)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0);
+ return asyncCallWithArgumentList(QLatin1String("WriteNDEFData"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void PropertyChanged(const QString &in0, const QDBusVariant &in1);
+};
+
+namespace com {
+ namespace nokia {
+ namespace nfc {
+ typedef ::ComNokiaNfcTagInterface Tag;
+ }
+ }
+}
+#endif
diff --git a/src/nfc/maemo6/target_interface.cpp b/src/nfc/maemo6/target_interface.cpp
new file mode 100644
index 00000000..ce64a6f2
--- /dev/null
+++ b/src/nfc/maemo6/target_interface.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -p target_interface_p.h:target_interface.cpp com.nokia.nfc.Target.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "target_interface_p.h"
+
+/*
+ * Implementation of interface class ComNokiaNfcTargetInterface
+ */
+
+ComNokiaNfcTargetInterface::ComNokiaNfcTargetInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+ComNokiaNfcTargetInterface::~ComNokiaNfcTargetInterface()
+{
+}
+
diff --git a/src/nfc/maemo6/target_interface_p.h b/src/nfc/maemo6/target_interface_p.h
new file mode 100644
index 00000000..a4a7dced
--- /dev/null
+++ b/src/nfc/maemo6/target_interface_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This file was generated by qdbusxml2cpp version 0.7 and then hand edited
+ * Command line was: qdbusxml2cpp -p target_interface_p.h:target_interface.cpp com.nokia.nfc.Target.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ */
+
+#ifndef TARGET_INTERFACE_P_H
+#define TARGET_INTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface com.nokia.nfc.Target
+ */
+class ComNokiaNfcTargetInterface: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "com.nokia.nfc.Target"; }
+
+public:
+ ComNokiaNfcTargetInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~ComNokiaNfcTargetInterface();
+
+ Q_PROPERTY(QString State READ state)
+ inline QString state()
+ {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QString();
+
+ return reply.value().value(QLatin1String("State")).toString();
+ }
+
+ Q_PROPERTY(QString Type READ type)
+ inline QString type()
+ {
+ QDBusReply<QVariantMap> reply = GetProperties();
+ if (!reply.isValid())
+ return QString();
+
+ return reply.value().value(QLatin1String("Type")).toString();
+ }
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<QVariantMap> GetProperties()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetProperty(const QString &in0, const QDBusVariant &in1)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
+ return asyncCallWithArgumentList(QLatin1String("SetProperty"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void PropertyChanged(const QString &in0, const QDBusVariant &in1);
+};
+
+namespace com {
+ namespace nokia {
+ namespace nfc {
+ typedef ::ComNokiaNfcTargetInterface Target;
+ }
+ }
+}
+#endif
diff --git a/src/nfc/nfc.pro b/src/nfc/nfc.pro
new file mode 100644
index 00000000..2616e096
--- /dev/null
+++ b/src/nfc/nfc.pro
@@ -0,0 +1,210 @@
+load(qt_module)
+
+TARGET = QtNfc
+QPRO_PWD = $PWD
+
+CONFIG += module
+MODULE_PRI = ../../modules/qt_nfc.pri
+
+QT = core
+
+DEFINES += QT_BUILD_NFC_LIB QT_MAKEDLL
+
+load(qt_module_config)
+
+PUBLIC_HEADERS += \
+ qnearfieldmanager.h \
+ qnearfieldtarget.h \
+ qndefrecord.h \
+ qndefnfctextrecord.h \
+ qndefmessage.h \
+ qndeffilter.h \
+ qndefnfcurirecord.h \
+ qnearfieldtagtype1.h \
+ qnearfieldtagtype2.h \
+ qllcpsocket.h \
+ qnearfieldtagtype3.h \
+ qnearfieldtagtype4.h \
+ qllcpserver.h \
+ qdeclarativendefrecord.h
+
+PRIVATE_HEADERS += \
+ qndefrecord_p.h \
+ qnearfieldtarget_p.h \
+ qnearfieldmanager_p.h \
+ qtlv_p.h \
+ checksum_p.h
+
+SOURCES += \
+ qnearfieldmanager.cpp \
+ qnearfieldtarget.cpp \
+ qndefrecord.cpp \
+ qndefnfctextrecord.cpp \
+ qndefmessage.cpp \
+ qndeffilter.cpp \
+ qndefnfcurirecord.cpp \
+ qnearfieldtagtype1.cpp \
+ qnearfieldtagtype2.cpp \
+ qnearfieldtagtype3.cpp \
+ qllcpsocket.cpp \
+ qnearfieldtagtype4.cpp \
+ qtlv.cpp \
+ qllcpserver.cpp \
+ qdeclarativendefrecord.cpp
+
+maemo6|meego {
+ NFC_BACKEND_AVAILABLE = yes
+
+ QT *= dbus
+
+ DBUS_INTERFACES += \
+ maemo6/com.nokia.nfc.Manager.xml
+
+ DBUS_ADAPTORS += \
+ maemo6/com.nokia.nfc.AccessRequestor.xml \
+ maemo6/com.nokia.nfc.NDEFHandler.xml
+
+ # work around bug in Qt
+ dbus_interface_source.depends = ${QMAKE_FILE_OUT_BASE}.h
+ dbus_adaptor_source.depends = ${QMAKE_FILE_OUT_BASE}.h
+
+ # Link against libdbus until Qt has support for passing file descriptors over DBus.
+ CONFIG += link_pkgconfig
+ DEFINES += DBUS_API_SUBJECT_TO_CHANGE
+ PKGCONFIG += dbus-1
+
+ PRIVATE_HEADERS += \
+ qnearfieldmanager_maemo6_p.h \
+ qnearfieldtarget_maemo6_p.h \
+ qllcpsocket_maemo6_p.h \
+ qllcpserver_maemo6_p.h \
+ maemo6/adapter_interface_p.h \
+ maemo6/target_interface_p.h \
+ maemo6/tag_interface_p.h \
+ maemo6/device_interface_p.h \
+ maemo6/socketrequestor_p.h
+
+ SOURCES += \
+ qnearfieldmanager_maemo6.cpp \
+ qnearfieldtarget_maemo6.cpp \
+ qllcpsocket_maemo6_p.cpp \
+ qllcpserver_maemo6_p.cpp \
+ maemo6/adapter_interface.cpp \
+ maemo6/target_interface.cpp \
+ maemo6/tag_interface.cpp \
+ maemo6/device_interface.cpp \
+ maemo6/socketrequestor.cpp
+
+ OTHER_FILES += \
+ $$DBUS_INTERFACES \
+ $$DBUS_ADAPTORS \
+ maemo6/com.nokia.nfc.Adapter.xml \
+ maemo6/com.nokia.nfc.Target.xml \
+ maemo6/com.nokia.nfc.Tag.xml \
+ maemo6/com.nokia.nfc.Device.xml \
+ maemo6/com.nokia.nfc.LLCPRequestor.xml
+
+ # Add OUT_PWD to INCLUDEPATH so that creator picks up headers for generated files
+ # This is not needed for the build otherwise.
+ INCLUDEPATH += $$OUT_PWD
+}
+
+simulator {
+ NFC_BACKEND_AVAILABLE = yes
+
+ QT *= gui
+
+ PRIVATE_HEADERS += \
+ qnearfieldmanagervirtualbase_p.h \
+ qnearfieldmanager_simulator_p.h \
+ qllcpsocket_simulator_p.h \
+ qllcpserver_simulator_p.h
+
+ SOURCES += \
+ qnearfieldmanagervirtualbase.cpp \
+ qnearfieldmanager_simulator.cpp \
+ qllcpsocket_simulator_p.cpp \
+ qllcpserver_simulator_p.cpp
+}
+
+contains(nfc_symbian_enabled, yes):symbian {
+ NFC_BACKEND_AVAILABLE = yes
+
+ QT += serviceframework
+
+ PRIVATE_HEADERS += \
+ qnearfieldmanager_symbian_p.h \
+ qnearfieldtagtype1_symbian_p.h \
+ qnearfieldtagtype2_symbian_p.h \
+ qllcpsocket_symbian_p.h \
+ qllcpserver_symbian_p.h \
+ qllcpstate_symbian_p.h \
+ qnearfieldtagtype3_symbian_p.h \
+ qnearfieldtagtype4_symbian_p.h \
+ qnearfieldtagmifare_symbian_p.h \
+ qnearfieldllcpdevice_symbian_p.h \
+ symbian/nearfieldmanager_symbian.h \
+ symbian/nearfieldtag_symbian.h \
+ symbian/nearfieldndeftarget_symbian.h \
+ symbian/nearfieldtargetfactory_symbian.h \
+ symbian/nearfieldutility_symbian.h \
+ symbian/llcpserver_symbian.h \
+ symbian/llcpsockettype1_symbian.h \
+ symbian/llcpsockettype2_symbian.h \
+ symbian/nearfieldtagimpl_symbian.h \
+ symbian/nearfieldtagasyncrequest_symbian.h \
+ symbian/nearfieldtagndefoperationcallback_symbian.h \
+ symbian/nearfieldtagoperationcallback_symbian.h \
+ symbian/nearfieldtagndefrequest_symbian.h \
+ symbian/nearfieldtagcommandrequest_symbian.h \
+ symbian/nearfieldtagcommandsrequest_symbian.h \
+ symbian/debug.h \
+ symbian/nearfieldtagimplcommon_symbian.h
+
+ SOURCES += \
+ qnearfieldmanager_symbian.cpp \
+ qnearfieldtagtype1_symbian.cpp \
+ qnearfieldtagtype2_symbian.cpp \
+ qllcpsocket_symbian_p.cpp \
+ qllcpserver_symbian_p.cpp \
+ qllcpstate_symbian_p.cpp \
+ qnearfieldtagtype3_symbian.cpp \
+ qnearfieldtagtype4_symbian.cpp \
+ qnearfieldtagmifare_symbian.cpp \
+ qnearfieldllcpdevice_symbian.cpp \
+ symbian/nearfieldmanager_symbian.cpp \
+ symbian/nearfieldtag_symbian.cpp \
+ symbian/nearfieldndeftarget_symbian.cpp \
+ symbian/nearfieldtargetfactory_symbian.cpp \
+ symbian/nearfieldutility_symbian.cpp \
+ symbian/llcpserver_symbian.cpp \
+ symbian/llcpsockettype1_symbian.cpp \
+ symbian/llcpsockettype2_symbian.cpp \
+ symbian/nearfieldtagasyncrequest_symbian.cpp \
+ symbian/nearfieldtagndefrequest_symbian.cpp \
+ symbian/nearfieldtagcommandrequest_symbian.cpp \
+ symbian/nearfieldtagcommandsrequest_symbian.cpp \
+ symbian/nearfieldtagimplcommon_symbian.cpp
+
+ INCLUDEPATH += $${EPOCROOT}epoc32/include/mw
+
+ LIBS += -lnfc -lndef -lndefaccess -lnfcdiscoveryservice -lllcp -lnfctagextension
+}
+
+isEmpty(NFC_BACKEND_AVAILABLE) {
+ # unsupported platform stub
+
+ PRIVATE_HEADERS += \
+ qllcpsocket_p.h \
+ qllcpserver_p.h \
+ qnearfieldmanagerimpl_p.h
+
+ SOURCES += \
+ qllcpsocket_p.cpp \
+ qllcpserver_p.cpp \
+ qnearfieldmanagerimpl_p.cpp
+}
+
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
diff --git a/src/nfc/qdeclarativendefrecord.cpp b/src/nfc/qdeclarativendefrecord.cpp
new file mode 100644
index 00000000..6b974084
--- /dev/null
+++ b/src/nfc/qdeclarativendefrecord.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativendefrecord.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QRegExp>
+
+/*!
+ \class QDeclarativeNdefRecord
+ \brief The QDeclarativeNdefRecord class implements the NdefRecord element in QML.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ \sa NdefRecord
+
+ The QDeclarativeNdefRecord class is the base class for all NdefRecord elements in QML. To
+ support a new NDEF record type in QML subclass this class and expose new properties, member
+ functions and signals appropriate for the new record type. The following must be done to
+ create a new NDEF record type in QML:
+
+ \list
+ \o The subclass must have a Q_OBJECT macro in its declaration.
+ \o The subclass must have an \l {Q_INVOKABLE}{invokable} constructor that takes a
+ QNdefRecord and a QObject pointer.
+ \o The subclass must be declared as an NDEF record by expanding the Q_DECLARE_NDEFRECORD()
+ macro in the implementation file of the subclass.
+ \o The subclass must be registered with QML.
+ \endlist
+
+ For example the declaration of such a class may look like the following.
+
+ \snippet snippets/connectivity/foorecord.h Foo declaration
+
+ Within the implementation file the Q_DECLARE_NDEFRECORD() macro is expanded:
+
+ \snippet snippets/connectivity/foorecord.cpp Declare foo record
+
+ Finially the application or plugin code calls qmlRegisterType():
+
+ \code
+ qmlRegisterType<QDeclarativeNdefFooRecord>(uri, 1, 0, "NdefFooRecord");
+ \endcode
+*/
+
+/*!
+ \qmlclass NdefRecord QDeclarativeNdefRecord
+ \brief The NdefRecord element represents a record in an NDEF message.
+
+ \ingroup connectivity-qml
+ \inmodule QtConnectivity
+
+ \sa NdefFilter
+ \sa NearField
+
+ \sa QNdefRecord
+
+ The NdefRecord element is the base element for all NDEF record elements in QML. It contains
+ a single property holding the type of record.
+
+ This class is not intended to be used directly, but extended from C++.
+
+ \sa QDeclarativeNdefRecord
+*/
+
+/*!
+ \qmlproperty string NdefRecord::recordType
+
+ This property holds the fully qualified record type of the NDEF record. The fully qualified
+ record type includes the NIS and NSS prefixes.
+*/
+
+/*!
+ \fn void QDeclarativeNdefRecord::recordTypeChanged()
+
+ This signal is emitted when the record type changes.
+*/
+
+/*!
+ \property QDeclarativeNdefRecord::recordType
+
+ This property hold the record type of the NDEF record that this class represents.
+*/
+
+/*!
+ \macro Q_DECLARE_NDEFRECORD(className, typeNameFormat, type)
+ \relates QDeclarativeNdefRecord
+
+ This macro ensures that \a className is declared as the class implementing the NDEF record
+ identified by \a typeNameFormat and \a type.
+
+ This macro should be expanded in the implementation file for \a className.
+*/
+
+static QMap<QString, const QMetaObject *> registeredNdefRecordTypes;
+
+class QDeclarativeNdefRecordPrivate
+{
+public:
+ QNdefRecord record;
+};
+
+static QString urnForRecordType(QNdefRecord::TypeNameFormat typeNameFormat, const QByteArray &type)
+{
+ switch (typeNameFormat) {
+ case QNdefRecord::NfcRtd:
+ return QLatin1String("urn:nfc:wkt:") + type;
+ case QNdefRecord::ExternalRtd:
+ return QLatin1String("urn:nfc:ext:") + type;
+ case QNdefRecord::Mime:
+ return QLatin1String("urn:nfc:mime:") + type;
+ default:
+ return QString();
+ }
+}
+
+/*!
+ \internal
+*/
+void qRegisterNdefRecordTypeHelper(const QMetaObject *metaObject,
+ QNdefRecord::TypeNameFormat typeNameFormat,
+ const QByteArray &type)
+{
+ registeredNdefRecordTypes.insert(urnForRecordType(typeNameFormat, type), metaObject);
+}
+
+/*!
+ \internal
+*/
+QDeclarativeNdefRecord *qNewDeclarativeNdefRecordForNdefRecord(const QNdefRecord &record)
+{
+ const QString urn = urnForRecordType(record.typeNameFormat(), record.type());
+
+ QMapIterator<QString, const QMetaObject *> i(registeredNdefRecordTypes);
+ while (i.hasNext()) {
+ i.next();
+
+ QRegExp ex(i.key());
+ if (!ex.exactMatch(urn))
+ continue;
+
+ const QMetaObject *metaObject = i.value();
+ if (!metaObject)
+ continue;
+
+ return static_cast<QDeclarativeNdefRecord *>(metaObject->newInstance(
+ Q_ARG(QNdefRecord, record), Q_ARG(QObject *, 0)));
+ }
+
+ return new QDeclarativeNdefRecord(record);
+}
+
+/*!
+ Constructs a new empty QDeclarativeNdefRecord with \a parent.
+*/
+QDeclarativeNdefRecord::QDeclarativeNdefRecord(QObject *parent)
+: QObject(parent), d_ptr(new QDeclarativeNdefRecordPrivate)
+{
+}
+
+/*!
+ Constructs a new QDeclarativeNdefRecord representing \a record. The parent of the newly
+ constructed object will be set to \a parent.
+*/
+QDeclarativeNdefRecord::QDeclarativeNdefRecord(const QNdefRecord &record, QObject *parent)
+: QObject(parent), d_ptr(new QDeclarativeNdefRecordPrivate)
+{
+ d_ptr->record = record;
+}
+
+/*!
+ Returns the fully qualified record type of the record. The fully qualified record type
+ includes both the NIS and NSS prefixes.
+*/
+QString QDeclarativeNdefRecord::recordType() const
+{
+ Q_D(const QDeclarativeNdefRecord);
+
+ if (d->record.typeNameFormat() == QNdefRecord::Empty)
+ return QString();
+
+ return urnForRecordType(d->record.typeNameFormat(), d->record.type());
+}
+
+/*!
+ Sets the record type to \a type if it is not currently equal to \a type; otherwise does
+ nothing. If the record type is set the recordTypeChanged() signal will be emitted.
+*/
+void QDeclarativeNdefRecord::setRecordType(const QString &type)
+{
+ if (type == recordType())
+ return;
+
+ Q_D(QDeclarativeNdefRecord);
+
+ if (type.startsWith(QLatin1String("urn:nfc:wkt:"))) {
+ d->record.setTypeNameFormat(QNdefRecord::NfcRtd);
+ d->record.setType(type.mid(12).toUtf8());
+ } else if (type.startsWith(QLatin1String("urn:nfc:ext:"))) {
+ d->record.setTypeNameFormat(QNdefRecord::ExternalRtd);
+ d->record.setType(type.mid(12).toUtf8());
+ } else if (type.startsWith(QLatin1String("urn:nfc:mime:"))) {
+ d->record.setTypeNameFormat(QNdefRecord::Mime);
+ d->record.setType(type.mid(13).toUtf8());
+ } else {
+ qWarning("Don't know how to decode NDEF type %s\n", qPrintable(type));
+ }
+
+ emit recordTypeChanged();
+}
+
+/*!
+ Returns a copy of the record.
+*/
+QNdefRecord QDeclarativeNdefRecord::record() const
+{
+ Q_D(const QDeclarativeNdefRecord);
+
+ return d->record;
+}
+
+/*!
+ Sets the record to \a record.
+*/
+void QDeclarativeNdefRecord::setRecord(const QNdefRecord &record)
+{
+ Q_D(QDeclarativeNdefRecord);
+
+ d->record = record;
+}
+
+#include "moc_qdeclarativendefrecord.cpp"
diff --git a/src/nfc/qdeclarativendefrecord.h b/src/nfc/qdeclarativendefrecord.h
new file mode 100644
index 00000000..8448b196
--- /dev/null
+++ b/src/nfc/qdeclarativendefrecord.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVENDEFRECORD_P_H
+#define QDECLARATIVENDEFRECORD_P_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMetaType>
+
+#include <qndefrecord.h>
+
+QT_BEGIN_HEADER
+
+class QDeclarativeNdefRecordPrivate;
+
+class Q_CONNECTIVITY_EXPORT QDeclarativeNdefRecord : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDeclarativeNdefRecord)
+
+ Q_PROPERTY(QString recordType READ recordType WRITE setRecordType NOTIFY recordTypeChanged)
+
+public:
+ explicit QDeclarativeNdefRecord(QObject *parent = 0);
+ explicit QDeclarativeNdefRecord(const QNdefRecord &record, QObject *parent = 0);
+
+ QString recordType() const;
+ void setRecordType(const QString &t);
+
+ QNdefRecord record() const;
+ void setRecord(const QNdefRecord &record);
+
+signals:
+ void recordTypeChanged();
+
+private:
+ QDeclarativeNdefRecordPrivate *d_ptr;
+};
+
+void Q_CONNECTIVITY_EXPORT qRegisterNdefRecordTypeHelper(const QMetaObject *metaObject,
+ QNdefRecord::TypeNameFormat typeNameFormat,
+ const QByteArray &type);
+
+Q_CONNECTIVITY_EXPORT QDeclarativeNdefRecord *qNewDeclarativeNdefRecordForNdefRecord(const QNdefRecord &record);
+
+template<typename T>
+bool qRegisterNdefRecordType(QNdefRecord::TypeNameFormat typeNameFormat, const QByteArray &type)
+{
+ qRegisterNdefRecordTypeHelper(&T::staticMetaObject, typeNameFormat, type);
+ return true;
+}
+
+#define Q_DECLARE_NDEFRECORD(className, typeNameFormat, type) \
+static bool _q_##className##_registered = qRegisterNdefRecordType<className>(typeNameFormat, type);
+
+QT_END_HEADER
+
+#endif // QDECLARATIVENDEFRECORD_P_H
diff --git a/src/nfc/qllcpserver.cpp b/src/nfc/qllcpserver.cpp
new file mode 100644
index 00000000..f7f165e6
--- /dev/null
+++ b/src/nfc/qllcpserver.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpserver.h"
+
+#if defined(QT_SIMULATOR)
+#include "qllcpserver_simulator_p.h"
+#elif defined(Q_OS_SYMBIAN)
+#include "qllcpserver_symbian_p.h"
+#elif defined(Q_WS_MAEMO_6) || defined(Q_WS_MEEGO)
+#include "qllcpserver_maemo6_p.h"
+#else
+#include "qllcpserver_p.h"
+#endif
+
+/*!
+ \class QLlcpServer
+ \brief The QLlcpServer class provides an NFC LLCP socket based server.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ This class makes it possible to accept incoming LLCP socket connections.
+
+ Call listen() to have the server start listening for incoming connections on a specified port.
+ The newConnection() signal is then emitted each time a client connects to the server.
+
+ Call nextPendingConnection() to accept the pending connection as a connected QLlcpSocket. The
+ function returns a pointer to a QLlcpSocket that can be used for communicating with the client.
+
+ If an error occurs, serverError() returns the type of error, and errorString() can be called to
+ get a human readable description of what happened.
+
+ When listening for connections, the port which the server is listening on is available through
+ serverPort().
+
+ Calling close() makes QLlcpServer stop listening for incoming connections.
+*/
+
+/*!
+ \fn QLlcpServer::newConnection()
+
+ This signal is emitted every time a new connection is available.
+
+ \sa hasPendingConnections(), nextPendingConnection()
+*/
+
+/*!
+ Constructs a new NFC LLCP server with \a parent.
+*/
+QLlcpServer::QLlcpServer(QObject *parent)
+: QObject(parent), d_ptr(new QLlcpServerPrivate(this))
+{
+}
+
+/*!
+ Destroys the NFC LLCP server.
+*/
+QLlcpServer::~QLlcpServer()
+{
+ delete d_ptr;
+}
+
+/*!
+ Tells the server to listen for incoming connections on \a serviceUri. If the server is
+ currently listening then it will return false. Returns true on success; otherwise returns
+ false.
+
+ serviceUri() will return the \a serviceUri that is passed into listen.
+
+ serverPort() will return the port that is assigned to the server.
+
+ \sa serverPort(), isListening(), close()
+*/
+bool QLlcpServer::listen(const QString &serviceUri)
+{
+ Q_D(QLlcpServer);
+
+ return d->listen(serviceUri);
+}
+
+/*!
+ Returns true if the server is listening for incoming connections; otherwise returns false.
+*/
+bool QLlcpServer::isListening() const
+{
+ Q_D(const QLlcpServer);
+
+ return d->isListening();
+}
+
+/*!
+ Stops listening for incoming connections.
+*/
+void QLlcpServer::close()
+{
+ Q_D(QLlcpServer);
+
+ d->close();
+}
+
+/*!
+ Returns the LLCP service URI that the server is listening on.
+*/
+QString QLlcpServer::serviceUri() const
+{
+ Q_D(const QLlcpServer);
+
+ return d->serviceUri();
+}
+
+/*!
+ Returns the LLCP port associated with the service URI that the server is listening on.
+
+ \note This call is not supported on all platforms and will return 0 on these platforms.
+*/
+quint8 QLlcpServer::serverPort() const
+{
+ Q_D(const QLlcpServer);
+
+ return d->serverPort();
+}
+
+/*!
+ Returns true if the server has a pending connection; otherwise returns false.
+
+ \sa nextPendingConnection()
+*/
+bool QLlcpServer::hasPendingConnections() const
+{
+ Q_D(const QLlcpServer);
+
+ return d->hasPendingConnections();
+}
+
+/*!
+ Returns the next pending connection as a connected QLlcpSocket object.
+
+ The socket is created as a child of the server, which means that it is automatically deleted
+ when the QLlcpServer object is destroyed. It is still a good idea to delete the object
+ explicitly when you are done with it, to avoid wasting memory.
+
+ 0 is returned if this function is called when there are no pending connections.
+
+ \sa hasPendingConnections(), newConnection()
+*/
+QLlcpSocket *QLlcpServer::nextPendingConnection()
+{
+ Q_D(QLlcpServer);
+
+ return d->nextPendingConnection();
+}
+
+/*!
+ Returns the last error that occurred.
+*/
+QLlcpSocket::SocketError QLlcpServer::serverError() const
+{
+ Q_D(const QLlcpServer);
+
+ return d->serverError();
+}
+
+#include "moc_qllcpserver.cpp"
diff --git a/src/nfc/qllcpserver.h b/src/nfc/qllcpserver.h
new file mode 100644
index 00000000..7a43b237
--- /dev/null
+++ b/src/nfc/qllcpserver.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSERVER_H
+#define QLLCPSERVER_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <qllcpsocket.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+class QLlcpServerPrivate;
+
+class Q_CONNECTIVITY_EXPORT QLlcpServer : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QLlcpServer)
+
+public:
+ explicit QLlcpServer(QObject *parent = 0);
+ virtual ~QLlcpServer();
+
+ bool listen(const QString &serviceUri);
+ bool isListening() const;
+
+ void close();
+
+ QString serviceUri() const;
+ quint8 serverPort() const;
+
+ virtual bool hasPendingConnections() const;
+ virtual QLlcpSocket *nextPendingConnection();
+
+ QLlcpSocket::SocketError serverError() const;
+
+Q_SIGNALS:
+ void newConnection();
+
+private:
+ QLlcpServerPrivate *d_ptr;
+};
+
+QT_END_HEADER
+
+#endif // QLLCPSERVER_H
diff --git a/src/nfc/qllcpserver_maemo6_p.cpp b/src/nfc/qllcpserver_maemo6_p.cpp
new file mode 100644
index 00000000..2b964bc1
--- /dev/null
+++ b/src/nfc/qllcpserver_maemo6_p.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpserver_maemo6_p.h"
+
+#include "manager_interface.h"
+#include "maemo6/adapter_interface_p.h"
+#include "qllcpsocket_maemo6_p.h"
+#include "maemo6/socketrequestor_p.h"
+
+using namespace com::nokia::nfc;
+
+static QAtomicInt requestorId = 0;
+static const char * const requestorBasePath = "/com/nokia/nfc/llcpserver/";
+
+QLlcpServerPrivate::QLlcpServerPrivate(QLlcpServer *q)
+: q_ptr(q),
+ m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, QUuid::createUuid())),
+ m_socketRequestor(0)
+{
+}
+
+bool QLlcpServerPrivate::listen(const QString &serviceUri)
+{
+ if (m_requestorPath.isEmpty()) {
+ m_requestorPath = QLatin1String(requestorBasePath) +
+ QString::number(requestorId.fetchAndAddOrdered(1));
+ }
+
+ Manager manager(QLatin1String("com.nokia.nfc"), QLatin1String("/"), m_connection);
+ QDBusObjectPath defaultAdapterPath = manager.DefaultAdapter();
+
+ if (!m_socketRequestor) {
+ m_socketRequestor = new SocketRequestor(defaultAdapterPath.path(), this);
+
+ connect(m_socketRequestor, SIGNAL(accessFailed(QDBusObjectPath,QString,QString)),
+ this, SLOT(AccessFailed(QDBusObjectPath,QString,QString)));
+ connect(m_socketRequestor, SIGNAL(accessGranted(QDBusObjectPath,QString)),
+ this, SLOT(AccessGranted(QDBusObjectPath,QString)));
+ connect(m_socketRequestor, SIGNAL(accept(QDBusVariant,QDBusVariant,int,QVariantMap)),
+ this, SLOT(Accept(QDBusVariant,QDBusVariant,int,QVariantMap)));
+ connect(m_socketRequestor, SIGNAL(connect(QDBusVariant,QDBusVariant,int,QVariantMap)),
+ this, SLOT(Connect(QDBusVariant,QDBusVariant,int,QVariantMap)));
+ connect(m_socketRequestor, SIGNAL(socket(QDBusVariant,int,QVariantMap)),
+ this, SLOT(Socket(QDBusVariant,int,QVariantMap)));
+ }
+
+ if (m_socketRequestor) {
+ QString accessKind(QLatin1String("device.llcp.co.server:") + serviceUri);
+ m_socketRequestor->requestAccess(m_requestorPath, accessKind);
+
+ m_serviceUri = serviceUri;
+ } else {
+ m_error = QLlcpSocket::SocketResourceError;
+
+ m_serviceUri.clear();
+ }
+
+ return !m_serviceUri.isEmpty();
+}
+
+bool QLlcpServerPrivate::isListening() const
+{
+ return !m_serviceUri.isEmpty();
+}
+
+void QLlcpServerPrivate::close()
+{
+ QString accessKind(QLatin1String("device.llcp.co.server:") + m_serviceUri);
+
+ m_socketRequestor->cancelAccessRequest(m_requestorPath, accessKind);
+
+ m_serviceUri.clear();
+}
+
+QString QLlcpServerPrivate::serviceUri() const
+{
+ return m_serviceUri;
+}
+
+quint8 QLlcpServerPrivate::serverPort() const
+{
+ return 0;
+}
+
+bool QLlcpServerPrivate::hasPendingConnections() const
+{
+ return !m_pendingSockets.isEmpty();
+}
+
+QLlcpSocket *QLlcpServerPrivate::nextPendingConnection()
+{
+ if (m_pendingSockets.isEmpty())
+ return 0;
+
+ QPair<int, QVariantMap> parameters = m_pendingSockets.takeFirst();
+
+ QLlcpSocketPrivate *socketPrivate =
+ new QLlcpSocketPrivate(m_connection, parameters.first, parameters.second);
+
+ QLlcpSocket *socket = new QLlcpSocket(socketPrivate, 0);
+
+ return socket;
+}
+
+QLlcpSocket::SocketError QLlcpServerPrivate::serverError() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
+
+void QLlcpServerPrivate::AccessFailed(const QDBusObjectPath &targetPath, const QString &kind,
+ const QString &error)
+{
+ Q_UNUSED(targetPath);
+ Q_UNUSED(kind);
+ Q_UNUSED(error);
+
+ m_serviceUri.clear();
+
+ m_error = QLlcpSocket::SocketAccessError;
+}
+
+void QLlcpServerPrivate::AccessGranted(const QDBusObjectPath &targetPath,
+ const QString &accessKind)
+{
+ Q_UNUSED(targetPath);
+ Q_UNUSED(accessKind);
+}
+
+void QLlcpServerPrivate::Accept(const QDBusVariant &lsap, const QDBusVariant &rsap,
+ int fd, const QVariantMap &properties)
+{
+ Q_UNUSED(lsap);
+ Q_UNUSED(rsap);
+ Q_UNUSED(properties);
+
+ Q_Q(QLlcpServer);
+
+ m_pendingSockets.append(qMakePair(fd, properties));
+
+ emit q->newConnection();
+}
+
+void QLlcpServerPrivate::Connect(const QDBusVariant &lsap, const QDBusVariant &rsap,
+ int readFd, const QVariantMap &properties)
+{
+ Q_UNUSED(lsap);
+ Q_UNUSED(rsap);
+ Q_UNUSED(readFd);
+ Q_UNUSED(properties);
+}
+
+void QLlcpServerPrivate::Socket(const QDBusVariant &lsap, int fd, const QVariantMap &properties)
+{
+ Q_UNUSED(lsap);
+ Q_UNUSED(fd);
+ Q_UNUSED(properties);
+}
+
+#include "moc_qllcpserver_maemo6_p.cpp"
diff --git a/src/nfc/qllcpserver_maemo6_p.h b/src/nfc/qllcpserver_maemo6_p.h
new file mode 100644
index 00000000..0543f321
--- /dev/null
+++ b/src/nfc/qllcpserver_maemo6_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSERVER_MAEMO6_P_H
+#define QLLCPSERVER_MAEMO6_P_H
+
+#include <qconnectivityglobal.h>
+
+#include "qllcpserver.h"
+
+#include <QtDBus/QDBusConnection>
+
+QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
+QT_FORWARD_DECLARE_CLASS(QDBusVariant)
+
+class AccessRequestorAdaptor;
+class LLCPRequestorAdaptor;
+
+class SocketRequestor;
+
+class QLlcpServerPrivate : public QObject
+{
+ Q_OBJECT
+
+ Q_DECLARE_PUBLIC(QLlcpServer)
+
+public:
+ QLlcpServerPrivate(QLlcpServer *q);
+
+ bool listen(const QString &serviceUri);
+ bool isListening() const;
+
+ void close();
+
+ QString serviceUri() const;
+ quint8 serverPort() const;
+
+ bool hasPendingConnections() const;
+ QLlcpSocket *nextPendingConnection();
+
+ QLlcpSocket::SocketError serverError() const;
+
+private slots:
+ // com.nokia.nfc.AccessRequestor
+ void AccessFailed(const QDBusObjectPath &targetPath, const QString &kind,
+ const QString &error);
+ void AccessGranted(const QDBusObjectPath &targetPath, const QString &accessKind);
+
+ // com.nokia.nfc.LLCPRequestor
+ void Accept(const QDBusVariant &lsap, const QDBusVariant &rsap, int fd,
+ const QVariantMap &properties);
+ void Connect(const QDBusVariant &lsap, const QDBusVariant &rsap, int fd,
+ const QVariantMap &properties);
+ void Socket(const QDBusVariant &lsap, int fd, const QVariantMap &properties);
+
+private:
+ QLlcpServer *q_ptr;
+
+ QDBusConnection m_connection;
+
+ QString m_serviceUri;
+
+ QString m_requestorPath;
+ SocketRequestor *m_socketRequestor;
+
+ QList<QPair<int, QVariantMap> > m_pendingSockets;
+
+ QLlcpSocket::SocketError m_error;
+};
+
+#endif // QLLCPSERVER_MAEMO6_P_H
diff --git a/src/nfc/qllcpserver_p.cpp b/src/nfc/qllcpserver_p.cpp
new file mode 100644
index 00000000..1e21ee34
--- /dev/null
+++ b/src/nfc/qllcpserver_p.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpserver_p.h"
+
+QLlcpServerPrivate::QLlcpServerPrivate(QLlcpServer *q)
+: q_ptr(q)
+{
+}
+
+QLlcpServerPrivate::~QLlcpServerPrivate()
+{
+}
+
+bool QLlcpServerPrivate::listen(const QString &serviceUri)
+{
+ Q_UNUSED(serviceUri);
+
+ return false;
+}
+
+bool QLlcpServerPrivate::isListening() const
+{
+ return false;
+}
+
+void QLlcpServerPrivate::close()
+{
+}
+
+QString QLlcpServerPrivate::serviceUri() const
+{
+ return QString();
+}
+
+quint8 QLlcpServerPrivate::serverPort() const
+{
+ return 0;
+}
+
+bool QLlcpServerPrivate::hasPendingConnections() const
+{
+ return false;
+}
+
+QLlcpSocket *QLlcpServerPrivate::nextPendingConnection()
+{
+ return 0;
+}
+
+QLlcpSocket::SocketError QLlcpServerPrivate::serverError() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
diff --git a/src/nfc/qllcpserver_p.h b/src/nfc/qllcpserver_p.h
new file mode 100644
index 00000000..e0a57ec3
--- /dev/null
+++ b/src/nfc/qllcpserver_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSERVER_P_H
+#define QLLCPSERVER_P_H
+
+#include "../qtconnectivityglobal.h"
+
+#include "qllcpserver.h"
+
+class QLlcpServerPrivate
+{
+ Q_DECLARE_PUBLIC(QLlcpServer)
+
+public:
+ QLlcpServerPrivate(QLlcpServer *q);
+ ~QLlcpServerPrivate();
+
+ bool listen(const QString &serviceUri);
+ bool isListening() const;
+
+ void close();
+
+ QString serviceUri() const;
+ quint8 serverPort() const;
+
+ bool hasPendingConnections() const;
+ QLlcpSocket *nextPendingConnection();
+
+ QLlcpSocket::SocketError serverError() const;
+
+private:
+ QLlcpServer *q_ptr;
+};
+
+#endif // QLLCPSERVER_P_H
diff --git a/src/nfc/qllcpserver_simulator_p.cpp b/src/nfc/qllcpserver_simulator_p.cpp
new file mode 100644
index 00000000..5ef6f963
--- /dev/null
+++ b/src/nfc/qllcpserver_simulator_p.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpserver_simulator_p.h"
+
+QLlcpServerPrivate::QLlcpServerPrivate(QLlcpServer *q)
+: q_ptr(q)
+{
+}
+
+bool QLlcpServerPrivate::listen(const QString &serviceUri)
+{
+ Q_UNUSED(serviceUri);
+
+ return false;
+}
+
+bool QLlcpServerPrivate::isListening() const
+{
+ return false;
+}
+
+void QLlcpServerPrivate::close()
+{
+}
+
+QString QLlcpServerPrivate::serviceUri() const
+{
+ return QString();
+}
+
+quint8 QLlcpServerPrivate::serverPort() const
+{
+ return 0;
+}
+
+bool QLlcpServerPrivate::hasPendingConnections() const
+{
+ return false;
+}
+
+QLlcpSocket *QLlcpServerPrivate::nextPendingConnection()
+{
+ return 0;
+}
+
+QLlcpSocket::SocketError QLlcpServerPrivate::serverError() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
diff --git a/src/nfc/qllcpserver_simulator_p.h b/src/nfc/qllcpserver_simulator_p.h
new file mode 100644
index 00000000..dfda5b5d
--- /dev/null
+++ b/src/nfc/qllcpserver_simulator_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSERVER_P_H
+#define QLLCPSERVER_P_H
+
+#include <qconnectivityglobal.h>
+
+#include "qllcpserver.h"
+
+class QLlcpServerPrivate
+{
+public:
+ QLlcpServerPrivate(QLlcpServer *q);
+
+ bool listen(const QString &serviceUri);
+ bool isListening() const;
+
+ void close();
+
+ QString serviceUri() const;
+ quint8 serverPort() const;
+
+ bool hasPendingConnections() const;
+ QLlcpSocket *nextPendingConnection();
+
+ QLlcpSocket::SocketError serverError() const;
+
+private:
+ QLlcpServer *q_ptr;
+};
+
+#endif // QLLCPSERVER_P_H
diff --git a/src/nfc/qllcpserver_symbian_p.cpp b/src/nfc/qllcpserver_symbian_p.cpp
new file mode 100644
index 00000000..4497ae15
--- /dev/null
+++ b/src/nfc/qllcpserver_symbian_p.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpserver_symbian_p.h"
+#include "symbian/llcpserver_symbian.h"
+#include "symbian/llcpsockettype2_symbian.h"
+#include "symbian/nearfieldutility_symbian.h"
+
+#include "symbian/debug.h"
+
+QLlcpServerPrivate::QLlcpServerPrivate(QLlcpServer *q)
+ :q_ptr(q)
+{
+ BEGIN
+ QT_TRAP_THROWING(m_symbianbackend = CLlcpServer::NewL(*this));
+ END
+}
+QLlcpServerPrivate::~QLlcpServerPrivate()
+{
+ BEGIN
+ close();
+ delete m_symbianbackend;
+ END
+}
+
+bool QLlcpServerPrivate::listen(const QString &serviceUri)
+{
+ BEGIN
+ LOG(serviceUri);
+ HBufC8* uri = NULL;
+ TRAPD(err, uri = QNFCNdefUtility::QString2HBufC8L(serviceUri));
+ if(err != KErrNone)
+ {
+ return false;
+ }
+ bool ret = m_symbianbackend->Listen(*uri);
+
+ delete uri;
+ END
+ return ret;
+}
+
+bool QLlcpServerPrivate::isListening() const
+{
+ BEGIN
+ END
+ return m_symbianbackend->isListening();
+}
+
+/*!
+ Stops listening for incoming connections.
+*/
+void QLlcpServerPrivate::close()
+{
+ BEGIN
+ m_symbianbackend->StopListening();
+ qDeleteAll(m_pendingConnections);
+ m_pendingConnections.clear();
+ END
+}
+
+QString QLlcpServerPrivate::serviceUri() const
+{
+ BEGIN
+ const TDesC8& uri= m_symbianbackend->serviceUri();
+
+ QString ret = QNFCNdefUtility::TDesC82QStringL(uri);
+ LOG("QLlcpServerPrivate::serviceUri() ret="<<ret);
+ END
+ return ret;
+
+}
+
+quint8 QLlcpServerPrivate::serverPort() const
+{
+ BEGIN
+ END
+ return 0;
+}
+
+bool QLlcpServerPrivate::hasPendingConnections() const
+{
+ BEGIN
+ END
+ return m_symbianbackend->hasPendingConnections();
+}
+
+void QLlcpServerPrivate::invokeNewConnection()
+{
+ BEGIN
+ Q_Q(QLlcpServer);
+ emit q->newConnection();
+ END
+}
+
+QLlcpSocket *QLlcpServerPrivate::nextPendingConnection()
+{
+ BEGIN
+ QLlcpSocket* qSocket = NULL;
+ CLlcpSocketType2* socket_symbian = m_symbianbackend->nextPendingConnection();
+ if (socket_symbian)
+ {
+ QLlcpSocketPrivate *qSocket_p = new QLlcpSocketPrivate(socket_symbian);
+ qSocket = new QLlcpSocket(qSocket_p,NULL);
+ qSocket_p->attachCallbackHandler(qSocket);
+ socket_symbian->AttachCallbackHandler(qSocket_p);
+ QPointer<QLlcpSocket> p(qSocket);
+ m_pendingConnections.append(p);
+ }
+ END
+ return qSocket;
+}
+
+QLlcpSocket::SocketError QLlcpServerPrivate::serverError() const
+{
+ BEGIN
+ END
+ return QLlcpSocket::UnknownSocketError;
+}
+
+//EOF
+
diff --git a/src/nfc/qllcpserver_symbian_p.h b/src/nfc/qllcpserver_symbian_p.h
new file mode 100644
index 00000000..e8d67654
--- /dev/null
+++ b/src/nfc/qllcpserver_symbian_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSERVER_SYMBIAN_P_H
+#define QLLCPSERVER_SYMBIAN_P_H
+
+#include <qconnectivityglobal.h>
+#include "qllcpserver.h"
+#include <QList>
+#include <QPointer>
+
+class CLlcpServer;
+class CLlcpSocketType2;
+class QLlcpSocket;
+
+QT_BEGIN_HEADER
+
+class QLlcpServerPrivate
+{
+ Q_DECLARE_PUBLIC(QLlcpServer)
+public:
+ QLlcpServerPrivate(QLlcpServer *q);
+ ~QLlcpServerPrivate();
+
+ bool listen(const QString &serviceUri);
+ bool isListening() const;
+
+ void close();
+
+ QString serviceUri() const;
+ quint8 serverPort() const;
+
+ bool hasPendingConnections() const;
+ QLlcpSocket *nextPendingConnection();
+ QLlcpSocket::SocketError serverError() const;
+
+public:
+ void invokeNewConnection();
+
+private:
+ CLlcpServer* m_symbianbackend;
+ QLlcpServer *q_ptr;
+ QList<QPointer<QLlcpSocket> > m_pendingConnections;
+};
+
+QT_END_HEADER
+
+#endif // QLLCPSERVER_P_H
diff --git a/src/nfc/qllcpsocket.cpp b/src/nfc/qllcpsocket.cpp
new file mode 100644
index 00000000..5b7e9e65
--- /dev/null
+++ b/src/nfc/qllcpsocket.cpp
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpsocket.h"
+
+#if defined(QT_SIMULATOR)
+#include "qllcpsocket_simulator_p.h"
+#elif defined(Q_OS_SYMBIAN)
+#include "qllcpsocket_symbian_p.h"
+#elif defined(Q_WS_MAEMO_6) || defined(Q_WS_MEEGO)
+#include "qllcpsocket_maemo6_p.h"
+#else
+#include "qllcpsocket_p.h"
+#endif
+
+/*!
+ \class QLlcpSocket
+ \brief The QLlcpSocket class provides an NFC LLCP socket.
+ \since 5.0
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+
+ NFC LLCP protocol is a peer-to-peer communication protocol between two NFC compliant devices.
+*/
+
+/*!
+ \enum QLlcpSocket::SocketError
+
+ This enum describes the errors that can occur. The most recent error can be retrieved through a
+ call to error().
+
+ \value UnknownSocketError An unidentified error has occurred.
+ \value RemoteHostClosedError The remote host closed the connection.
+ \value SocketAccessError The socket operation failed because the application lacked the
+ required privileges.
+ \value SocketResourceError The local system ran out of resources (e.g., too many sockets).
+*/
+
+/*!
+ \enum QLlcpSocket::SocketState
+
+ This enum describes the different state in which a socket can be.
+
+ \value UnconnectedState The socket is not connected.
+ \value ConnectingState The socket has started establishing a connection.
+ \value ConnectedState A connection is established.
+ \value ClosingState The socket is about to close.
+ \value BoundState The socket is bound to a local port (for servers).
+ \value ListeningState The socket is listening for incoming connections (for internal use).
+*/
+
+/*!
+ \fn QLlcpSocket::connected()
+
+ This signal is emitted after connectToService() has been called and a connection has been
+ successfully established.
+
+ \sa connectToService(), disconnected()
+*/
+
+/*!
+ \fn QLlcpSocket::disconnected()
+
+ This signal is emitted when the socket has been disconnected.
+
+ \sa disconnectFromService(),
+*/
+
+/*!
+ \fn QLlcpSocket::error(QLlcpSocket::SocketError socketError)
+
+ This signal is emitted when an error occurs. The \a socketError parameter describes the error.
+*/
+
+/*!
+ \fn QLlcpSocket::stateChanged(QLlcpSocket::SocketState socketState)
+
+ This signal is emitted when the state of the socket changes. The \a socketState parameter
+ describes the new state.
+*/
+
+/*!
+ Construct a new unconnected LLCP socket with \a parent.
+*/
+QLlcpSocket::QLlcpSocket(QObject *parent)
+: QIODevice(parent), d_ptr(new QLlcpSocketPrivate(this))
+{
+ setOpenMode(QIODevice::NotOpen);
+}
+
+/*!
+ \internal
+*/
+QLlcpSocket::QLlcpSocket(QLlcpSocketPrivate *d, QObject *parent)
+: QIODevice(parent), d_ptr(d)
+{
+ setOpenMode(QIODevice::ReadWrite);
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys the LLCP socket.
+*/
+QLlcpSocket::~QLlcpSocket()
+{
+ delete d_ptr;
+}
+
+/*!
+ Connects to the service identified by the URI \a serviceUri on \a target.
+*/
+void QLlcpSocket::connectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ Q_D(QLlcpSocket);
+
+ d->connectToService(target, serviceUri);
+}
+
+/*!
+ Disconnects the socket.
+*/
+void QLlcpSocket::disconnectFromService()
+{
+ Q_D(QLlcpSocket);
+
+ d->disconnectFromService();
+}
+
+/*!
+ Disconnects the socket.
+*/
+void QLlcpSocket::close()
+{
+ Q_D(QLlcpSocket);
+
+ QIODevice::close();
+
+ d->disconnectFromService();
+}
+
+/*!
+ Binds the LLCP socket to local \a port. Returns true on success; otherwise returns false.
+*/
+bool QLlcpSocket::bind(quint8 port)
+{
+ Q_D(QLlcpSocket);
+
+ return d->bind(port);
+}
+
+/*!
+ Returns true if at least one datagram (service data units) is waiting to be read; otherwise
+ returns false.
+
+ \sa pendingDatagramSize(), readDatagram()
+*/
+bool QLlcpSocket::hasPendingDatagrams() const
+{
+ Q_D(const QLlcpSocket);
+
+ return d->hasPendingDatagrams();
+}
+
+/*!
+ Returns the size of the first pending datagram (service data unit). If there is no datagram
+ available, this function returns -1.
+
+ \sa hasPendingDatagrams(), readDatagram()
+*/
+qint64 QLlcpSocket::pendingDatagramSize() const
+{
+ Q_D(const QLlcpSocket);
+
+ return d->pendingDatagramSize();
+}
+
+/*!
+ Sends the datagram at \a data of size \a size to the service that this socket is connected to.
+ Returns the number of bytes sent on success; otherwise return -1;
+*/
+qint64 QLlcpSocket::writeDatagram(const char *data, qint64 size)
+{
+ Q_D(QLlcpSocket);
+
+ return d->writeDatagram(data, size);
+}
+
+/*!
+ \reimp
+
+ Always returns true.
+*/
+bool QLlcpSocket::isSequential() const
+{
+ return true;
+}
+
+/*!
+ \overload
+
+ Sends the datagram \a datagram to the service that this socket is connected to.
+*/
+qint64 QLlcpSocket::writeDatagram(const QByteArray &datagram)
+{
+ Q_D(QLlcpSocket);
+
+ return d->writeDatagram(datagram);
+}
+
+/*!
+ Receives a datagram no larger than \a maxSize bytes and stores it in \a data. The sender's
+ details are stored in \a target and \a port (unless the pointers are 0).
+
+ Returns the size of the datagram on success; otherwise returns -1.
+
+ If maxSize is too small, the rest of the datagram will be lost. To avoid loss of data, call
+ pendingDatagramSize() to determine the size of the pending datagram before attempting to read
+ it. If maxSize is 0, the datagram will be discarded.
+
+ \sa writeDatagram(), hasPendingDatagrams(), pendingDatagramSize()
+*/
+qint64 QLlcpSocket::readDatagram(char *data, qint64 maxSize, QNearFieldTarget **target,
+ quint8 *port)
+{
+ Q_D(QLlcpSocket);
+
+ return d->readDatagram(data, maxSize, target, port);
+}
+
+/*!
+ Sends the datagram at \a data of size \a size to the service identified by the URI
+ \a port on \a target. Returns the number of bytes sent on success; otherwise returns -1.
+
+ \sa readDatagram()
+*/
+qint64 QLlcpSocket::writeDatagram(const char *data, qint64 size, QNearFieldTarget *target,
+ quint8 port)
+{
+ Q_D(QLlcpSocket);
+
+ return d->writeDatagram(data, size, target, port);
+}
+
+/*!
+ \overload
+
+ Sends the datagram \a datagram to the service identified by the URI \a port on \a target.
+*/
+qint64 QLlcpSocket::writeDatagram(const QByteArray &datagram, QNearFieldTarget *target,
+ quint8 port)
+{
+ Q_D(QLlcpSocket);
+
+ return d->writeDatagram(datagram, target, port);
+}
+
+/*!
+ Returns the type of error that last occurred.
+*/
+QLlcpSocket::SocketError QLlcpSocket::error() const
+{
+ Q_D(const QLlcpSocket);
+
+ return d->error();
+}
+
+/*!
+ Returns the state of the socket.
+*/
+QLlcpSocket::SocketState QLlcpSocket::state() const
+{
+ Q_D(const QLlcpSocket);
+
+ return d->state();
+}
+
+/*!
+ \reimp
+*/
+qint64 QLlcpSocket::bytesAvailable() const
+{
+ Q_D(const QLlcpSocket);
+
+ return d->bytesAvailable() + QIODevice::bytesAvailable();
+}
+
+/*!
+ \reimp
+*/
+bool QLlcpSocket::canReadLine() const
+{
+ Q_D(const QLlcpSocket);
+
+ return d->canReadLine() || QIODevice::canReadLine();
+}
+
+/*!
+ \reimp
+*/
+bool QLlcpSocket::waitForReadyRead(int msecs)
+{
+ Q_D(QLlcpSocket);
+
+ return d->waitForReadyRead(msecs);
+}
+
+/*!
+ \reimp
+*/
+bool QLlcpSocket::waitForBytesWritten(int msecs)
+{
+ Q_D(QLlcpSocket);
+
+ return d->waitForBytesWritten(msecs);
+}
+
+/*!
+ Waits until the socket is connected, up to \a msecs milliseconds. If the connection has been
+ established, this function returns true; otherwise it returns false. In the case where it
+ returns false, you can call error() to determine the cause of the error.
+
+ If msecs is -1, this function will not time out.
+*/
+bool QLlcpSocket::waitForConnected(int msecs)
+{
+ Q_D(QLlcpSocket);
+
+ return d->waitForConnected(msecs);
+}
+
+/*!
+ Waits until the socket is disconnected, up to \a msecs milliseconds. If the connection has been
+ disconnected, this function returns true; otherwise it returns false. In the case where it
+ returns false, you can call error() to determine the cause of the error.
+
+ If msecs is -1, this function will not time out.
+*/
+bool QLlcpSocket::waitForDisconnected(int msecs)
+{
+ Q_D(QLlcpSocket);
+
+ return d->waitForDisconnected(msecs);
+}
+
+/*!
+ \internal
+*/
+qint64 QLlcpSocket::readData(char *data, qint64 maxlen)
+{
+ Q_D(QLlcpSocket);
+
+ return d->readData(data, maxlen);
+}
+
+/*!
+ \internal
+*/
+qint64 QLlcpSocket::writeData(const char *data, qint64 len)
+{
+ Q_D(QLlcpSocket);
+
+ return d->writeData(data, len);
+}
+
+#include <moc_qllcpsocket.cpp>
diff --git a/src/nfc/qllcpsocket.h b/src/nfc/qllcpsocket.h
new file mode 100644
index 00000000..7e916b95
--- /dev/null
+++ b/src/nfc/qllcpsocket.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKET_H
+#define QLLCPSOCKET_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QIODevice>
+#include <QtNetwork/QAbstractSocket>
+
+QT_BEGIN_HEADER
+
+class QNearFieldTarget;
+class QLlcpSocketPrivate;
+
+class Q_CONNECTIVITY_EXPORT QLlcpSocket : public QIODevice
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QLlcpSocket)
+
+ friend class QLlcpServerPrivate;
+
+public:
+ enum SocketState {
+ UnconnectedState = QAbstractSocket::UnconnectedState,
+ ConnectingState = QAbstractSocket::ConnectingState,
+ ConnectedState = QAbstractSocket::ConnectedState,
+ ClosingState = QAbstractSocket::ClosingState,
+ BoundState = QAbstractSocket::BoundState,
+ ListeningState = QAbstractSocket::ListeningState
+ };
+
+ enum SocketError {
+ UnknownSocketError = QAbstractSocket::UnknownSocketError,
+ RemoteHostClosedError = QAbstractSocket::RemoteHostClosedError,
+ SocketAccessError = QAbstractSocket::SocketAccessError,
+ SocketResourceError = QAbstractSocket::SocketResourceError
+ };
+
+ explicit QLlcpSocket(QObject *parent = 0);
+ ~QLlcpSocket();
+
+ void connectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void disconnectFromService();
+
+ void close();
+
+ bool bind(quint8 port);
+
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 writeDatagram(const char *data, qint64 size);
+ qint64 writeDatagram(const QByteArray &datagram);
+
+ qint64 readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = 0, quint8 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ qint64 writeDatagram(const QByteArray &datagram, QNearFieldTarget *target, quint8 port);
+
+ SocketError error() const;
+ SocketState state() const;
+
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+
+ bool waitForReadyRead(int msecs = 30000);
+ bool waitForBytesWritten(int msecs = 30000);
+ virtual bool waitForConnected(int msecs = 30000);
+ virtual bool waitForDisconnected(int msecs = 30000);
+ bool isSequential() const;
+
+Q_SIGNALS:
+ void connected();
+ void disconnected();
+ void error(QLlcpSocket::SocketError socketError);
+ void stateChanged(QLlcpSocket::SocketState socketState);
+
+protected:
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+private:
+ QLlcpSocket(QLlcpSocketPrivate *d, QObject *parent);
+
+ QLlcpSocketPrivate *d_ptr;
+};
+
+QT_END_HEADER
+
+#endif // QLLCPSOCKET_H
diff --git a/src/nfc/qllcpsocket_maemo6_p.cpp b/src/nfc/qllcpsocket_maemo6_p.cpp
new file mode 100644
index 00000000..a2cd15f6
--- /dev/null
+++ b/src/nfc/qllcpsocket_maemo6_p.cpp
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpsocket_maemo6_p.h"
+
+#include "manager_interface.h"
+#include "maemo6/adapter_interface_p.h"
+#include "maemo6/socketrequestor_p.h"
+
+#include <QtCore/QSocketNotifier>
+#include <QtCore/QAtomicInt>
+
+#include <errno.h>
+#include <signal.h>
+
+using namespace com::nokia::nfc;
+
+static QAtomicInt requestorId = 0;
+static const char * const requestorBasePath = "/com/nokia/nfc/llcpclient/";
+
+QLlcpSocketPrivate::QLlcpSocketPrivate(QLlcpSocket *q)
+: q_ptr(q),
+ m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, QUuid::createUuid())),
+ m_port(0), m_socketRequestor(0), m_fd(-1), m_readNotifier(0), m_writeNotifier(0),
+ m_pendingBytes(0), m_state(QLlcpSocket::UnconnectedState),
+ m_error(QLlcpSocket::UnknownSocketError)
+{
+}
+
+QLlcpSocketPrivate::QLlcpSocketPrivate(const QDBusConnection &connection, int fd,
+ const QVariantMap &properties)
+: q_ptr(0), m_properties(properties), m_connection(connection), m_port(0), m_socketRequestor(0),
+ m_fd(fd), m_pendingBytes(0),
+ m_state(QLlcpSocket::ConnectedState), m_error(QLlcpSocket::UnknownSocketError)
+{
+ m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(_q_readNotify()));
+ m_writeNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Write, this);
+ connect(m_writeNotifier, SIGNAL(activated(int)), this, SLOT(_q_bytesWritten()));
+}
+
+QLlcpSocketPrivate::~QLlcpSocketPrivate()
+{
+ delete m_readNotifier;
+ delete m_writeNotifier;
+}
+
+void QLlcpSocketPrivate::connectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ Q_UNUSED(target);
+
+ Q_Q(QLlcpSocket);
+
+ m_state = QLlcpSocket::ConnectingState;
+ emit q->stateChanged(m_state);
+
+ initializeRequestor();
+
+ if (m_socketRequestor) {
+ m_serviceUri = serviceUri;
+ m_port = 0;
+
+ QString accessKind(QLatin1String("device.llcp.co.client:") + serviceUri);
+
+ m_socketRequestor->requestAccess(m_requestorPath, accessKind);
+ } else {
+ setSocketError(QLlcpSocket::SocketResourceError);
+
+ m_state = QLlcpSocket::UnconnectedState;
+ emit q->stateChanged(m_state);
+ }
+}
+
+void QLlcpSocketPrivate::disconnectFromService()
+{
+ Q_Q(QLlcpSocket);
+
+ m_state = QLlcpSocket::ClosingState;
+ emit q->stateChanged(m_state);
+
+ delete m_readNotifier;
+ m_readNotifier = 0;
+ delete m_writeNotifier;
+ m_writeNotifier = 0;
+ m_pendingBytes = 0;
+ ::close(m_fd);
+ m_fd = -1;
+
+ if (m_socketRequestor) {
+ QString accessKind(QLatin1String("device.llcp.co.client:") + m_serviceUri);
+
+ Manager manager(QLatin1String("com.nokia.nfc"), QLatin1String("/"), m_connection);
+ QDBusObjectPath defaultAdapterPath = manager.DefaultAdapter();
+
+ m_socketRequestor->cancelAccessRequest(m_requestorPath, accessKind);
+ }
+
+ m_state = QLlcpSocket::UnconnectedState;
+ q->setOpenMode(QIODevice::NotOpen);
+ emit q->stateChanged(m_state);
+ emit q->disconnected();
+}
+
+bool QLlcpSocketPrivate::bind(quint8 port)
+{
+ initializeRequestor();
+
+ if (!m_socketRequestor)
+ return false;
+
+ m_serviceUri.clear();
+ m_port = port;
+
+ const QString accessKind(QLatin1String("device.llcp.cl:") + QString::number(port));
+
+ m_socketRequestor->requestAccess(m_requestorPath, accessKind);
+
+ return waitForBound(30000);
+}
+
+bool QLlcpSocketPrivate::hasPendingDatagrams() const
+{
+ return !m_receivedDatagrams.isEmpty();
+}
+
+qint64 QLlcpSocketPrivate::pendingDatagramSize() const
+{
+ if (m_receivedDatagrams.isEmpty())
+ return -1;
+
+ if (m_state == QLlcpSocket::BoundState)
+ return m_receivedDatagrams.first().length() - 1;
+ else
+ return m_receivedDatagrams.first().length();
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size)
+{
+ if (m_state != QLlcpSocket::ConnectedState)
+ return -1;
+
+ return writeData(data, size);
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram)
+{
+ if (m_state != QLlcpSocket::ConnectedState)
+ return -1;
+
+ if (uint(datagram.length()) > m_properties.value(QLatin1String("RemoteMIU"), 128).toUInt())
+ return -1;
+
+ return writeData(datagram.constData(), datagram.size());
+}
+
+qint64 QLlcpSocketPrivate::readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ Q_UNUSED(target);
+
+ if (m_state == QLlcpSocket::ConnectedState) {
+ return readData(data, maxSize);
+ } else if (m_state == QLlcpSocket::BoundState) {
+ return readData(data, maxSize, port);
+ }
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(target);
+
+ if (m_state != QLlcpSocket::BoundState)
+ return -1;
+
+ if (m_properties.value(QLatin1String("RemoteMIU"), 128).toUInt() < size)
+ return -1;
+
+ if (m_properties.value(QLatin1String("LocalMIU"), 128).toUInt() < size)
+ return -1;
+
+ QByteArray datagram;
+ datagram.append(port);
+ datagram.append(data, size);
+
+ m_pendingBytes += datagram.size() - 1;
+ m_writeNotifier->setEnabled(true);
+
+ return ::write(m_fd, datagram.constData(), datagram.size()) - 1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(target);
+
+ if (m_state != QLlcpSocket::BoundState)
+ return -1;
+
+ if (m_properties.value(QLatin1String("RemoteMIU"), 128).toInt() < datagram.size())
+ return -1;
+
+ if (m_properties.value(QLatin1String("LocalMIU"), 128).toInt() < datagram.size())
+ return -1;
+
+ QByteArray d;
+ d.append(port);
+ d.append(datagram);
+
+ m_pendingBytes += datagram.size() - 1;
+ m_writeNotifier->setEnabled(true);
+
+ return ::write(m_fd, d.constData(), d.size()) - 1;
+}
+
+QLlcpSocket::SocketError QLlcpSocketPrivate::error() const
+{
+ return m_error;
+}
+
+QLlcpSocket::SocketState QLlcpSocketPrivate::state() const
+{
+ return m_state;
+}
+
+qint64 QLlcpSocketPrivate::readData(char *data, qint64 maxlen, quint8 *port)
+{
+ if (m_receivedDatagrams.isEmpty())
+ return 0;
+
+ const QByteArray datagram = m_receivedDatagrams.takeFirst();
+
+ if (m_state == QLlcpSocket::BoundState) {
+ if (port)
+ *port = datagram.at(0);
+
+ qint64 size = qMin(maxlen, qint64(datagram.length() - 1));
+ memcpy(data, datagram.constData() + 1, size);
+ return size;
+ } else {
+ if (port)
+ *port = 0;
+
+ qint64 size = qMin(maxlen, qint64(datagram.length()));
+ memcpy(data, datagram.constData(), size);
+ return size;
+ }
+}
+
+qint64 QLlcpSocketPrivate::writeData(const char *data, qint64 len)
+{
+ Q_Q(QLlcpSocket);
+
+ qint64 remoteMiu = m_properties.value(QLatin1String("RemoteMIU"), 128).toLongLong();
+ qint64 localMiu = m_properties.value(QLatin1String("LocalMIU"), 128).toLongLong();
+ qint64 miu = qMin(remoteMiu, localMiu);
+
+ m_writeNotifier->setEnabled(true);
+
+ ssize_t wrote = ::write(m_fd, data, qMin(miu, len));
+ if (wrote == -1) {
+ if (errno == EAGAIN)
+ return 0;
+
+ setSocketError(QLlcpSocket::RemoteHostClosedError);
+ q->disconnectFromService();
+ return -1;
+ }
+
+ m_pendingBytes += wrote;
+ return wrote;
+}
+
+qint64 QLlcpSocketPrivate::bytesAvailable() const
+{
+ qint64 available = 0;
+ foreach (const QByteArray &datagram, m_receivedDatagrams)
+ available += datagram.length();
+
+ // less source port
+ if (m_state == QLlcpSocket::BoundState)
+ available -= m_receivedDatagrams.count();
+
+ return available;
+}
+
+bool QLlcpSocketPrivate::canReadLine() const
+{
+ if (m_state == QLlcpSocket::BoundState)
+ return false;
+
+ foreach (const QByteArray &datagram, m_receivedDatagrams) {
+ if (datagram.contains('\n'))
+ return true;
+ }
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForReadyRead(int msec)
+{
+ if (bytesAvailable())
+ return true;
+
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ timeval timeout;
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_usec = (msec % 1000) * 1000;
+
+ // timeout can not be 0 or else select will return an error.
+ if (0 == msec)
+ timeout.tv_usec = 1000;
+
+ int result = -1;
+ // on Linux timeout will be updated by select, but _not_ on other systems.
+ QElapsedTimer timer;
+ timer.start();
+ while (!bytesAvailable() && (-1 == msec || timer.elapsed() < msec)) {
+ result = ::select(m_fd + 1, &fds, 0, 0, &timeout);
+ if (result > 0)
+ _q_readNotify();
+
+ if (-1 == result && errno != EINTR) {
+ setSocketError(QLlcpSocket::UnknownSocketError);
+ break;
+ }
+ }
+
+ return bytesAvailable();
+}
+
+bool QLlcpSocketPrivate::waitForBytesWritten(int msec)
+{
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ timeval timeout;
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_usec = (msec % 1000) * 1000;
+
+ // timeout can not be 0 or else select will return an error.
+ if (0 == msec)
+ timeout.tv_usec = 1000;
+
+ int result = -1;
+ // on Linux timeout will be updated by select, but _not_ on other systems.
+ QElapsedTimer timer;
+ timer.start();
+ while (-1 == msec || timer.elapsed() < msec) {
+ result = ::select(m_fd + 1, 0, &fds, 0, &timeout);
+ if (result > 0)
+ return true;
+ if (-1 == result && errno != EINTR) {
+ setSocketError(QLlcpSocket::UnknownSocketError);
+ return false;
+ }
+ }
+
+ // timeout expired
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForConnected(int msecs)
+{
+ if (m_state != QLlcpSocket::ConnectingState)
+ return m_state == QLlcpSocket::ConnectedState;
+
+ QElapsedTimer timer;
+ timer.start();
+ while (m_state == QLlcpSocket::ConnectingState && (msecs == -1 || timer.elapsed() < msecs)) {
+ if (!m_socketRequestor->waitForDBusSignal(qMax(msecs - timer.elapsed(), qint64(0)))) {
+ setSocketError(QLlcpSocket::UnknownSocketError);
+ break;
+ }
+ }
+
+ // Possibly not needed.
+ QCoreApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+ return m_state == QLlcpSocket::ConnectedState;
+}
+
+bool QLlcpSocketPrivate::waitForDisconnected(int msec)
+{
+ if (m_state == QLlcpSocket::UnconnectedState)
+ return true;
+
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ timeval timeout;
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_usec = (msec % 1000) * 1000;
+
+ // timeout can not be 0 or else select will return an error.
+ if (0 == msec)
+ timeout.tv_usec = 1000;
+
+ int result = -1;
+ // on Linux timeout will be updated by select, but _not_ on other systems.
+ QElapsedTimer timer;
+ timer.start();
+ while (m_state != QLlcpSocket::UnconnectedState && (-1 == msec || timer.elapsed() < msec)) {
+ result = ::select(m_fd + 1, &fds, 0, 0, &timeout);
+ if (result > 0)
+ _q_readNotify();
+
+ if (-1 == result && errno != EINTR) {
+ setSocketError(QLlcpSocket::UnknownSocketError);
+ break;
+ }
+ }
+
+ return m_state == QLlcpSocket::UnconnectedState;
+}
+
+bool QLlcpSocketPrivate::waitForBound(int msecs)
+{
+ if (m_state == QLlcpSocket::BoundState)
+ return true;
+
+ QElapsedTimer timer;
+ timer.start();
+ while (m_state != QLlcpSocket::BoundState && (msecs == -1 || timer.elapsed() < msecs)) {
+ if (!m_socketRequestor->waitForDBusSignal(qMax(msecs - timer.elapsed(), qint64(0))))
+ return false;
+ }
+
+ // Possibly not needed.
+ QCoreApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+ return m_state == QLlcpSocket::BoundState;
+}
+
+void QLlcpSocketPrivate::AccessFailed(const QDBusObjectPath &targetPath, const QString &kind,
+ const QString &error)
+{
+ Q_UNUSED(targetPath);
+ Q_UNUSED(kind);
+ Q_UNUSED(error);
+
+ Q_Q(QLlcpSocket);
+
+ setSocketError(QLlcpSocket::SocketAccessError);
+
+ m_state = QLlcpSocket::UnconnectedState;
+ emit q->stateChanged(m_state);
+}
+
+void QLlcpSocketPrivate::AccessGranted(const QDBusObjectPath &targetPath,
+ const QString &accessKind)
+{
+ Q_UNUSED(targetPath);
+ Q_UNUSED(accessKind);
+}
+
+void QLlcpSocketPrivate::Accept(const QDBusVariant &lsap, const QDBusVariant &rsap,
+ int fd, const QVariantMap &properties)
+{
+ Q_UNUSED(lsap);
+ Q_UNUSED(rsap);
+ Q_UNUSED(fd);
+ Q_UNUSED(properties);
+}
+
+void QLlcpSocketPrivate::Connect(const QDBusVariant &lsap, const QDBusVariant &rsap,
+ int fd, const QVariantMap &properties)
+{
+ Q_UNUSED(lsap);
+ Q_UNUSED(rsap);
+
+ m_fd = fd;
+
+ m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(_q_readNotify()));
+ m_writeNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Write, this);
+ connect(m_writeNotifier, SIGNAL(activated(int)), this, SLOT(_q_bytesWritten()));
+
+ m_properties = properties;
+
+ Q_Q(QLlcpSocket);
+
+ q->setOpenMode(QIODevice::ReadWrite);
+
+ m_state = QLlcpSocket::ConnectedState;
+ emit q->stateChanged(m_state);
+ emit q->connected();
+}
+
+void QLlcpSocketPrivate::Socket(const QDBusVariant &lsap, int fd, const QVariantMap &properties)
+{
+ m_fd = fd;
+ m_port = lsap.variant().toUInt();
+
+ m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(_q_readNotify()));
+ m_writeNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Write, this);
+ connect(m_writeNotifier, SIGNAL(activated(int)), this, SLOT(_q_bytesWritten()));
+
+ m_properties = properties;
+
+ Q_Q(QLlcpSocket);
+
+ m_state = QLlcpSocket::BoundState;
+ emit q->stateChanged(m_state);
+}
+
+void QLlcpSocketPrivate::_q_readNotify()
+{
+ Q_Q(QLlcpSocket);
+
+ QByteArray datagram;
+ datagram.resize(m_properties.value(QLatin1String("LocalMIU"), 128).toUInt());
+
+ int readFromDevice = ::read(m_fd, datagram.data(), datagram.size());
+ if (readFromDevice <= 0) {
+ m_readNotifier->setEnabled(false);
+
+ setSocketError(QLlcpSocket::RemoteHostClosedError);
+
+ q->disconnectFromService();
+ q->setOpenMode(QIODevice::NotOpen);
+ } else {
+ m_receivedDatagrams.append(datagram.left(readFromDevice));
+ emit q->readyRead();
+ }
+}
+
+void QLlcpSocketPrivate::_q_bytesWritten()
+{
+ Q_Q(QLlcpSocket);
+
+ m_writeNotifier->setEnabled(false);
+
+ emit q->bytesWritten(m_pendingBytes);
+ m_pendingBytes = 0;
+}
+
+void QLlcpSocketPrivate::setSocketError(QLlcpSocket::SocketError socketError)
+{
+ Q_Q(QLlcpSocket);
+
+ QLatin1String c("QLlcpSocket");
+
+ m_error = socketError;
+ switch (socketError) {
+ case QLlcpSocket::UnknownSocketError:
+ q->setErrorString(QLlcpSocket::tr("%1: Unknown error %2").arg(c).arg(errno));
+ break;
+ case QLlcpSocket::RemoteHostClosedError:
+ q->setErrorString(QLlcpSocket::tr("%1: Remote closed").arg(c));
+ break;
+ case QLlcpSocket::SocketAccessError:
+ q->setErrorString(QLlcpSocket::tr("%1: Socket access error"));
+ break;
+ case QLlcpSocket::SocketResourceError:
+ q->setErrorString(QLlcpSocket::tr("%1: Socket resource error"));
+ break;
+ }
+
+ emit q->error(m_error);
+}
+
+void QLlcpSocketPrivate::initializeRequestor()
+{
+ if (m_socketRequestor)
+ return;
+
+ if (m_requestorPath.isEmpty()) {
+ m_requestorPath = QLatin1String(requestorBasePath) +
+ QString::number(requestorId.fetchAndAddOrdered(1));
+ }
+
+ Manager manager(QLatin1String("com.nokia.nfc"), QLatin1String("/"), m_connection);
+ QDBusObjectPath defaultAdapterPath = manager.DefaultAdapter();
+
+ if (!m_socketRequestor) {
+ m_socketRequestor = new SocketRequestor(defaultAdapterPath.path(), this);
+
+ connect(m_socketRequestor, SIGNAL(accessFailed(QDBusObjectPath,QString,QString)),
+ this, SLOT(AccessFailed(QDBusObjectPath,QString,QString)));
+ connect(m_socketRequestor, SIGNAL(accessGranted(QDBusObjectPath,QString)),
+ this, SLOT(AccessGranted(QDBusObjectPath,QString)));
+ connect(m_socketRequestor, SIGNAL(accept(QDBusVariant,QDBusVariant,int,QVariantMap)),
+ this, SLOT(Accept(QDBusVariant,QDBusVariant,int,QVariantMap)));
+ connect(m_socketRequestor, SIGNAL(connect(QDBusVariant,QDBusVariant,int,QVariantMap)),
+ this, SLOT(Connect(QDBusVariant,QDBusVariant,int,QVariantMap)));
+ connect(m_socketRequestor, SIGNAL(socket(QDBusVariant,int,QVariantMap)),
+ this, SLOT(Socket(QDBusVariant,int,QVariantMap)));
+ }
+}
+
+#include "moc_qllcpsocket_maemo6_p.cpp"
diff --git a/src/nfc/qllcpsocket_maemo6_p.h b/src/nfc/qllcpsocket_maemo6_p.h
new file mode 100644
index 00000000..bfece31f
--- /dev/null
+++ b/src/nfc/qllcpsocket_maemo6_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKET_MAEMO6_P_H
+#define QLLCPSOCKET_MAEMO6_P_H
+
+#include <qconnectivityglobal.h>
+
+#include "qllcpsocket.h"
+
+#include <QtDBus/QDBusConnection>
+
+QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
+QT_FORWARD_DECLARE_CLASS(QDBusVariant)
+QT_FORWARD_DECLARE_CLASS(QSocketNotifier)
+
+class AccessRequestorAdaptor;
+class LLCPRequestorAdaptor;
+
+class SocketRequestor;
+
+class QLlcpSocketPrivate : public QObject
+{
+ Q_OBJECT
+
+ Q_DECLARE_PUBLIC(QLlcpSocket)
+
+public:
+ QLlcpSocketPrivate(QLlcpSocket *q);
+ QLlcpSocketPrivate(const QDBusConnection &connection, int fd, const QVariantMap &properties);
+ ~QLlcpSocketPrivate();
+
+ void connectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void disconnectFromService();
+
+ bool bind(quint8 port);
+
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 writeDatagram(const char *data, qint64 size);
+ qint64 writeDatagram(const QByteArray &datagram);
+
+ qint64 readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = 0, quint8 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ qint64 writeDatagram(const QByteArray &datagram, QNearFieldTarget *target, quint8 port);
+
+ QLlcpSocket::SocketError error() const;
+ QLlcpSocket::SocketState state() const;
+
+ qint64 readData(char *data, qint64 maxlex, quint8 *port = 0);
+ qint64 writeData(const char *data, qint64 len);
+
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+
+ bool waitForReadyRead(int msecs);
+ bool waitForBytesWritten(int msecs);
+ bool waitForConnected(int msecs);
+ bool waitForDisconnected(int msecs);
+ bool waitForBound(int msecs);
+
+private slots:
+ // com.nokia.nfc.AccessRequestor
+ void AccessFailed(const QDBusObjectPath &targetPath, const QString &kind,
+ const QString &error);
+ void AccessGranted(const QDBusObjectPath &targetPath, const QString &accessKind);
+
+ // com.nokia.nfc.LLCPRequestor
+ void Accept(const QDBusVariant &lsap, const QDBusVariant &rsap, int fd, const QVariantMap &properties);
+ void Connect(const QDBusVariant &lsap, const QDBusVariant &rsap, int fd, const QVariantMap &properties);
+ void Socket(const QDBusVariant &lsap, int fd, const QVariantMap &properties);
+
+ void _q_readNotify();
+ void _q_bytesWritten();
+
+private:
+ void setSocketError(QLlcpSocket::SocketError socketError);
+ void initializeRequestor();
+
+ QLlcpSocket *q_ptr;
+ QVariantMap m_properties;
+ QList<QByteArray> m_receivedDatagrams;
+
+ QDBusConnection m_connection;
+
+ QString m_serviceUri;
+ quint8 m_port;
+
+ QString m_requestorPath;
+
+ SocketRequestor *m_socketRequestor;
+
+ int m_fd;
+ QSocketNotifier *m_readNotifier;
+ QSocketNotifier *m_writeNotifier;
+ qint64 m_pendingBytes;
+
+ QLlcpSocket::SocketState m_state;
+ QLlcpSocket::SocketError m_error;
+};
+
+#endif // QLLCPSOCKET_MAEMO6_P_H
diff --git a/src/nfc/qllcpsocket_p.cpp b/src/nfc/qllcpsocket_p.cpp
new file mode 100644
index 00000000..820cbb64
--- /dev/null
+++ b/src/nfc/qllcpsocket_p.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpsocket_p.h"
+
+QLlcpSocketPrivate::QLlcpSocketPrivate(QLlcpSocket *q)
+: q_ptr(q)
+{
+}
+
+QLlcpSocketPrivate::~QLlcpSocketPrivate()
+{
+
+}
+
+void QLlcpSocketPrivate::connectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ Q_UNUSED(target);
+ Q_UNUSED(serviceUri);
+}
+
+void QLlcpSocketPrivate::disconnectFromService()
+{
+}
+
+bool QLlcpSocketPrivate::bind(quint8 port)
+{
+ Q_UNUSED(port);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::hasPendingDatagrams() const
+{
+ return false;
+}
+
+qint64 QLlcpSocketPrivate::pendingDatagramSize() const
+{
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(size);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram)
+{
+ Q_UNUSED(datagram);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxSize);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(size);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(datagram);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return -1;
+}
+
+QLlcpSocket::SocketError QLlcpSocketPrivate::error() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
+
+QLlcpSocket::SocketState QLlcpSocketPrivate::state() const
+{
+ return QLlcpSocket::UnconnectedState;
+}
+
+qint64 QLlcpSocketPrivate::readData(char *data, qint64 maxlen)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxlen);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::bytesAvailable() const
+{
+ return 0;
+}
+
+bool QLlcpSocketPrivate::canReadLine() const
+{
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForReadyRead(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForBytesWritten(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForConnected(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForDisconnected(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
diff --git a/src/nfc/qllcpsocket_p.h b/src/nfc/qllcpsocket_p.h
new file mode 100644
index 00000000..2dde2c1c
--- /dev/null
+++ b/src/nfc/qllcpsocket_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKET_P_H
+#define QLLCPSOCKET_P_H
+
+#include "../qtconnectivityglobal.h"
+
+#include "qllcpsocket.h"
+
+class QLlcpSocketPrivate
+{
+ Q_DECLARE_PUBLIC(QLlcpSocket)
+
+public:
+ QLlcpSocketPrivate(QLlcpSocket *q);
+
+ ~QLlcpSocketPrivate();
+
+ void connectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void disconnectFromService();
+
+ bool bind(quint8 port);
+
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 writeDatagram(const char *data, qint64 size);
+ qint64 writeDatagram(const QByteArray &datagram);
+
+ qint64 readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = 0, quint8 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ qint64 writeDatagram(const QByteArray &datagram, QNearFieldTarget *target, quint8 port);
+
+ QLlcpSocket::SocketError error() const;
+ QLlcpSocket::SocketState state() const;
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+
+ bool waitForReadyRead(int msecs);
+ bool waitForBytesWritten(int msecs);
+ bool waitForConnected(int msecs);
+ bool waitForDisconnected(int msecs);
+
+private:
+ QLlcpSocket *q_ptr;
+};
+
+#endif // QLLCPSOCKET_P_H
diff --git a/src/nfc/qllcpsocket_simulator_p.cpp b/src/nfc/qllcpsocket_simulator_p.cpp
new file mode 100644
index 00000000..2749c250
--- /dev/null
+++ b/src/nfc/qllcpsocket_simulator_p.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpsocket_simulator_p.h"
+
+QLlcpSocketPrivate::QLlcpSocketPrivate(QLlcpSocket *q)
+: q_ptr(q)
+{
+}
+
+void QLlcpSocketPrivate::connectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ Q_UNUSED(target);
+ Q_UNUSED(serviceUri);
+}
+
+void QLlcpSocketPrivate::disconnectFromService()
+{
+}
+
+bool QLlcpSocketPrivate::bind(quint8 port)
+{
+ Q_UNUSED(port);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::hasPendingDatagrams() const
+{
+ return false;
+}
+
+qint64 QLlcpSocketPrivate::pendingDatagramSize() const
+{
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(size);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram)
+{
+ Q_UNUSED(datagram);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxSize);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(size);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(datagram);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+
+ return -1;
+}
+
+QLlcpSocket::SocketError QLlcpSocketPrivate::error() const
+{
+ return QLlcpSocket::UnknownSocketError;
+}
+
+QLlcpSocket::SocketState QLlcpSocketPrivate::state() const
+{
+ return QLlcpSocket::UnconnectedState;
+}
+
+qint64 QLlcpSocketPrivate::readData(char *data, qint64 maxlen)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxlen);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return -1;
+}
+
+qint64 QLlcpSocketPrivate::bytesAvailable() const
+{
+ return 0;
+}
+
+bool QLlcpSocketPrivate::canReadLine() const
+{
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForReadyRead(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForBytesWritten(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForConnected(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
+bool QLlcpSocketPrivate::waitForDisconnected(int msecs)
+{
+ Q_UNUSED(msecs);
+
+ return false;
+}
+
diff --git a/src/nfc/qllcpsocket_simulator_p.h b/src/nfc/qllcpsocket_simulator_p.h
new file mode 100644
index 00000000..e232eda8
--- /dev/null
+++ b/src/nfc/qllcpsocket_simulator_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKET_P_H
+#define QLLCPSOCKET_P_H
+
+#include <qconnectivityglobal.h>
+
+#include "qllcpsocket.h"
+
+class QLlcpSocketPrivate
+{
+ Q_DECLARE_PUBLIC(QLlcpSocket)
+
+public:
+ QLlcpSocketPrivate(QLlcpSocket *q);
+
+ void connectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void disconnectFromService();
+
+ bool bind(quint8 port);
+
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 writeDatagram(const char *data, qint64 size);
+ qint64 writeDatagram(const QByteArray &datagram);
+
+ qint64 readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = 0, quint8 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ qint64 writeDatagram(const QByteArray &datagram, QNearFieldTarget *target, quint8 port);
+
+ QLlcpSocket::SocketError error() const;
+ QLlcpSocket::SocketState state() const;
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+
+ bool waitForReadyRead(int msecs);
+ bool waitForBytesWritten(int msecs);
+ bool waitForConnected(int msecs);
+ bool waitForDisconnected(int msecs);
+
+private:
+ QLlcpSocket *q_ptr;
+};
+
+#endif // QLLCPSOCKET_P_H
diff --git a/src/nfc/qllcpsocket_symbian_p.cpp b/src/nfc/qllcpsocket_symbian_p.cpp
new file mode 100644
index 00000000..ccf637f0
--- /dev/null
+++ b/src/nfc/qllcpsocket_symbian_p.cpp
@@ -0,0 +1,409 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qllcpsocket_symbian_p.h"
+#include "qllcpstate_symbian_p.h"
+#include "symbian/llcpsockettype1_symbian.h"
+#include "symbian/llcpsockettype2_symbian.h"
+#include "symbian/nearfieldutility_symbian.h"
+#include "symbian/debug.h"
+
+/*!
+ Constructor
+*/
+QLlcpSocketPrivate::QLlcpSocketPrivate(QLlcpSocket *q)
+ : m_symbianSocketType1(NULL),
+ m_symbianSocketType2(NULL),
+ m_error(QLlcpSocket::UnknownSocketError),
+ q_ptr(q),
+ m_emittedReadyRead(false),
+ m_emittedBytesWritten(false),
+ m_writeDatagramRefCount(0)
+{
+ BEGIN
+ m_unconnectedState = new QLLCPUnconnected(this);
+ m_connectingState = new QLLCPConnecting(this);
+ m_connectedState = new QLLCPConnected(this);
+ m_bindState = new QLLCPBind(this);
+
+ m_state = m_unconnectedState;
+ END
+}
+
+
+/*!
+ Destructor
+*/
+QLlcpSocketPrivate::~QLlcpSocketPrivate()
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ if (q->isOpen()) {
+ q->close();
+ }
+
+ delete m_unconnectedState;
+ delete m_connectingState;
+ delete m_connectedState;
+ delete m_bindState;
+ delete m_symbianSocketType1;
+ delete m_symbianSocketType2;
+ END
+}
+
+/*!
+ Construct the socket and set as connected state from llcp server side
+*/
+QLlcpSocketPrivate::QLlcpSocketPrivate(CLlcpSocketType2* socketType2_symbian)
+ : m_symbianSocketType1(NULL),
+ m_symbianSocketType2(socketType2_symbian),
+ m_error(QLlcpSocket::UnknownSocketError),
+ m_emittedReadyRead(false),
+ m_emittedBytesWritten(false),
+ m_writeDatagramRefCount(0)
+{
+ BEGIN
+ m_unconnectedState = new QLLCPUnconnected(this);
+ m_connectingState = new QLLCPConnecting(this);
+ m_connectedState = new QLLCPConnected(this);
+ m_bindState = new QLLCPBind(this);
+
+ m_state = m_connectedState;
+
+ END
+}
+
+void QLlcpSocketPrivate::connectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ if (!q->isOpen())
+ {
+ bool ret = q->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
+ if (false == ret)
+ invokeError();
+ }
+ m_state->ConnectToService(target,serviceUri);
+ END
+}
+
+void QLlcpSocketPrivate::disconnectFromService()
+{
+ BEGIN
+ m_state->DisconnectFromService();
+
+ Q_Q(QLlcpSocket);
+ if (q->isOpen())
+ {
+ q->close();
+ }
+ END
+}
+
+void QLlcpSocketPrivate::invokeConnected()
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+
+ if (m_state->state() == QLlcpSocket::ConnectingState)
+ {
+ changeState(getConnectedState());
+ invokeStateChanged(QLlcpSocket::ConnectedState);
+ emit q->connected();
+ }
+ END
+}
+
+void QLlcpSocketPrivate::invokeReadyRead()
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ //If called from within a slot connected to the readyRead() signal,
+ //readyRead() will not be reemitted.
+ LOG("m_emittedReadyRead: " << m_emittedReadyRead);
+
+ if (!m_emittedReadyRead){
+ m_emittedReadyRead = true;
+ LOG("readyRead signal has been emitted!");
+ emit q->readyRead();
+ m_emittedReadyRead = false;
+ }
+ END
+}
+
+void QLlcpSocketPrivate::attachCallbackHandler(QLlcpSocket *q)
+{
+ BEGIN
+ q_ptr = q;
+ if (!q->isOpen())
+ {
+ bool ret = q->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
+ if (false == ret)
+ invokeError();
+ }
+ END
+}
+
+qint64 QLlcpSocketPrivate::bytesAvailable() const
+{
+ BEGIN
+ qint64 bytes = 0;
+ if (m_symbianSocketType2 != NULL)
+ {
+ bytes = m_symbianSocketType2->BytesAvailable();
+ }
+ END
+ return bytes;
+}
+
+bool QLlcpSocketPrivate::canReadLine() const
+{
+ return false;
+}
+
+void QLlcpSocketPrivate::invokeBytesWritten(qint64 bytes)
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ if (!m_emittedBytesWritten){
+ m_emittedBytesWritten = true;
+ emit q->bytesWritten(bytes);
+ m_emittedBytesWritten = false;
+ }
+ END
+}
+
+void QLlcpSocketPrivate::invokeStateChanged(QLlcpSocket::SocketState socketState)
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ emit q->stateChanged(socketState);
+ END
+}
+
+void QLlcpSocketPrivate::invokeError()
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ emit q->error(QLlcpSocket::UnknownSocketError);
+ END
+}
+
+void QLlcpSocketPrivate::invokeDisconnected()
+{
+ BEGIN
+ Q_Q(QLlcpSocket);
+ emit q->disconnected();
+ END
+}
+
+/*!
+ Only used at connectless mode, create type1 socket if necessary.
+*/
+bool QLlcpSocketPrivate::bind(quint8 port)
+{
+ BEGIN_END
+ return m_state->Bind(port);
+}
+
+/*!
+ Returns true if at least one datagram is waiting to be read;
+ otherwise returns false.
+*/
+bool QLlcpSocketPrivate::hasPendingDatagrams() const
+{
+ BEGIN
+ bool val = false;
+ if (m_symbianSocketType1)
+ {
+ val = m_symbianSocketType1->HasPendingDatagrams();
+ }
+
+ END
+ return val;
+}
+
+/*!
+ Returns the size of the first pending connectionless datagram. If there is
+ no datagram available, this function returns -1.
+*/
+qint64 QLlcpSocketPrivate::pendingDatagramSize() const
+{
+ BEGIN
+ qint64 val = -1;
+ if (m_symbianSocketType1)
+ {
+ val = m_symbianSocketType1->PendingDatagramSize();
+ }
+
+ END
+ return val;
+}
+
+CLlcpSocketType1* QLlcpSocketPrivate::socketType1Instance()
+{
+ if (NULL == m_symbianSocketType1)
+ {
+ TRAPD(err, m_symbianSocketType1 = CLlcpSocketType1::NewL(*this));
+ if (KErrNone != err) {
+ m_symbianSocketType1 = NULL;
+ }
+ }
+ return m_symbianSocketType1;
+}
+
+CLlcpSocketType2* QLlcpSocketPrivate::socketType2Instance()
+{
+ if (NULL == m_symbianSocketType2)
+ {
+ TRAPD(err, m_symbianSocketType2 = CLlcpSocketType2::NewL(this));
+ if (KErrNone != err) {
+ m_symbianSocketType2 = NULL;
+ }
+ }
+ return m_symbianSocketType2;
+}
+
+/*!
+ Connection-Oriented Style
+*/
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size)
+{
+ BEGIN
+ qint64 val = -1;
+ val = m_state->WriteDatagram(data,size);
+ END
+ return val;
+}
+
+/*!
+ Connection-Oriented Style
+*/
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram)
+{
+ BEGIN_END
+ return writeDatagram(datagram.constData(),datagram.size());
+}
+
+/*!
+ Used for Both Connection-Less & Connection-Oriented Style
+ As for Connection-Oriented mode, can not pass in the port & target parameters.
+*/
+qint64 QLlcpSocketPrivate::readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ BEGIN
+ qint64 val = m_state->ReadDatagram(data,maxSize,target,port);
+ END
+ return val;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ BEGIN
+ qint64 val = m_state->WriteDatagram(data,size,target,port);
+ END
+
+ return val;
+}
+
+qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram,
+ QNearFieldTarget *target, quint8 port)
+{
+ BEGIN_END
+ return writeDatagram(datagram.constData(),datagram.size(),target,port);
+}
+
+QLlcpSocket::SocketError QLlcpSocketPrivate::error() const
+{
+ BEGIN_END
+ return m_error;
+}
+
+QLlcpSocket::SocketState QLlcpSocketPrivate::state() const
+{
+ BEGIN_END
+ return m_state->state();
+}
+
+qint64 QLlcpSocketPrivate::readData(char *data, qint64 maxlen)
+{
+ BEGIN_END
+ return readDatagram(data,maxlen);
+}
+
+qint64 QLlcpSocketPrivate::writeData(const char *data, qint64 len)
+{
+ BEGIN_END
+ return writeDatagram(data,len);
+}
+
+bool QLlcpSocketPrivate::waitForReadyRead(int msecs)
+{
+ BEGIN_END
+ return m_state->WaitForReadyRead(msecs);
+}
+
+bool QLlcpSocketPrivate::waitForBytesWritten(int msecs)
+{
+ BEGIN_END
+ return m_state->WaitForBytesWritten(msecs);
+}
+
+bool QLlcpSocketPrivate::waitForConnected(int msecs)
+{
+ BEGIN_END
+ return m_state->WaitForConnected(msecs);
+}
+
+bool QLlcpSocketPrivate::waitForDisconnected(int msecs)
+{
+ BEGIN_END
+ return m_state->WaitForDisconnected(msecs);
+}
+
+void QLlcpSocketPrivate::changeState(QLLCPSocketState* state)
+{
+ m_state = state;
+ BEGIN_END
+}
+
diff --git a/src/nfc/qllcpsocket_symbian_p.h b/src/nfc/qllcpsocket_symbian_p.h
new file mode 100644
index 00000000..8b4cebe4
--- /dev/null
+++ b/src/nfc/qllcpsocket_symbian_p.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKET_P_H
+#define QLLCPSOCKET_P_H
+
+#include <qconnectivityglobal.h>
+#include "qllcpsocket.h"
+
+#include <QtCore/QObject>
+#include <QSharedPointer>
+
+class CLlcpSocketType1;
+class CLlcpSocketType2;
+
+QT_BEGIN_HEADER
+
+class QLLCPSocketState;
+
+class QLlcpSocketPrivate
+{
+ Q_DECLARE_PUBLIC(QLlcpSocket)
+
+public:
+
+ QLlcpSocketPrivate(QLlcpSocket *q);
+ QLlcpSocketPrivate(CLlcpSocketType2* socketType2_symbian);
+ ~QLlcpSocketPrivate();
+
+public: //Implementation of QLlcpSocket API
+ void connectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void disconnectFromService();
+
+ bool bind(quint8 port);
+
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 writeDatagram(const char *data, qint64 size);
+ qint64 writeDatagram(const QByteArray &datagram);
+
+ qint64 readDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = 0, quint8 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ qint64 writeDatagram(const QByteArray &datagram, QNearFieldTarget *target, quint8 port);
+
+ QLlcpSocket::SocketError error() const;
+ QLlcpSocket::SocketState state() const;
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+
+ bool waitForReadyRead(int msecs);
+ bool waitForBytesWritten(int msecs);
+ bool waitForConnected(int msecs);
+ bool waitForDisconnected(int msecs);
+ void attachCallbackHandler(QLlcpSocket *q);
+
+public:
+ CLlcpSocketType1* socketType1Instance();
+ CLlcpSocketType2* socketType2Instance();
+ CLlcpSocketType1* socketType1Handler() {return m_symbianSocketType1;}
+ CLlcpSocketType2* socketType2Handler() {return m_symbianSocketType2;}
+
+ QLlcpSocket* qllcpsocket(CLlcpSocketType2*);
+
+public:
+ enum State {
+ ListeningState = QAbstractSocket::ListeningState,
+ };
+
+public:
+ void invokeReadyRead();
+ void invokeBytesWritten(qint64 bytes) ;
+ void invokeStateChanged(QLlcpSocket::SocketState socketState);
+ void invokeError();
+ void invokeDisconnected();
+ void invokeConnected();
+
+// state machine part
+public:
+ void changeState(QLLCPSocketState*);
+ QLLCPSocketState* getUnconnectedState() { return m_unconnectedState;}
+ QLLCPSocketState* getConnectedState() { return m_connectedState;}
+ QLLCPSocketState* getConnectingState() { return m_connectingState;}
+ QLLCPSocketState* getBindState() { return m_bindState;}
+
+private:
+ CLlcpSocketType1* m_symbianSocketType1; // own
+ CLlcpSocketType2* m_symbianSocketType2; // own
+
+private:
+ QLlcpSocket::SocketError m_error;
+ QLLCPSocketState* m_state; // not own
+ QLLCPSocketState* m_unconnectedState; // own
+ QLLCPSocketState* m_connectedState; // own
+ QLLCPSocketState* m_connectingState; // own
+ QLLCPSocketState* m_bindState; // own
+
+ QLlcpSocket *q_ptr; // not own
+
+ bool m_emittedReadyRead;
+ bool m_emittedBytesWritten;
+
+public:
+ int m_writeDatagramRefCount;
+};
+
+QT_END_HEADER
+
+#endif // QLLCPSOCKET_P_H
diff --git a/src/nfc/qllcpstate_symbian_p.cpp b/src/nfc/qllcpstate_symbian_p.cpp
new file mode 100644
index 00000000..35b03cc0
--- /dev/null
+++ b/src/nfc/qllcpstate_symbian_p.cpp
@@ -0,0 +1,551 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qllcpsocket_symbian_p.h"
+#include "qllcpstate_symbian_p.h"
+#include "symbian/llcpsockettype1_symbian.h"
+#include "symbian/llcpsockettype2_symbian.h"
+#include "symbian/nearfieldutility_symbian.h"
+
+#include "symbian/debug.h"
+
+QLLCPSocketState::QLLCPSocketState(QLlcpSocketPrivate* socket)
+ :m_socket(socket)
+{}
+
+/*!
+ Connection-Less Mode
+*/
+bool QLLCPUnconnected::Bind(quint8 port)
+{
+ BEGIN
+ bool ret = false;
+ if (connectionType2 == m_socketType) {
+ return ret;
+ }
+
+ CLlcpSocketType1* socketHandler = m_socket->socketType1Instance();
+ if (socketHandler != NULL )
+ {
+ if (connectionUnknown == m_socketType)
+ {
+ m_socketType = connectionType1;
+ }
+
+ if (socketHandler->Bind(port))
+ {
+ ret = true;
+ m_socket->changeState(m_socket->getBindState());
+ m_socket->invokeStateChanged(QLlcpSocket::BoundState);
+ }
+ }
+ END
+ return ret;
+}
+
+/*!
+ Connection-Less Mode
+*/
+bool QLLCPUnconnected::WaitForBytesWritten(int msecs)
+{
+ BEGIN
+ bool ret = false;
+ if (connectionType1 != m_socketType) {
+ return ret;
+ }
+
+ ret = WaitForBytesWrittenType1Private(msecs);
+ END
+ return ret;
+}
+
+bool QLLCPUnconnected::WaitForDisconnected(int msecs)
+{
+ Q_UNUSED(msecs);
+ BEGIN_END
+ return true;
+}
+
+/*!
+ Connection-Less Mode
+*/
+bool QLLCPBind::WaitForBytesWritten(int msecs)
+{
+ BEGIN
+ bool ret = WaitForBytesWrittenType1Private(msecs);
+ END
+ return ret;
+}
+
+/*!
+ Failitator function for Connection-Less Mode
+*/
+bool QLLCPSocketState::WaitForBytesWrittenType1Private(int msecs)
+{
+ bool ret = false;
+
+ qDebug() << "m_writeDatagramRefCount: " << m_socket->m_writeDatagramRefCount;
+ if (m_socket->m_writeDatagramRefCount <= 0)
+ {
+ return ret;
+ }
+
+ CLlcpSocketType1* socketHandler = m_socket->socketType1Instance();
+ if (socketHandler != NULL)
+ {
+ ret = socketHandler->WaitForBytesWritten(msecs);
+ }
+ return ret;
+}
+
+/*!
+ Connection-Less Mode
+*/
+bool QLLCPBind::WaitForReadyRead(int msecs)
+{
+ BEGIN
+ bool ret = false;
+ CLlcpSocketType1* socketHandler = m_socket->socketType1Instance();
+ if (socketHandler != NULL && socketHandler->HasPendingDatagrams())
+ {
+ ret = true;
+ }
+ END
+ return ret;
+}
+
+/*!
+ Connection-Less Mode
+*/
+qint64 QLLCPUnconnected::WriteDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ BEGIN
+ Q_UNUSED(target);
+ qint64 val = -1;
+
+ if (connectionType2 == m_socketType){
+ return val;
+ }
+
+ CLlcpSocketType1* socketHandler = m_socket->socketType1Instance();
+
+ if (socketHandler != NULL)
+ {
+ if (connectionUnknown == m_socketType)
+ {
+ m_socketType = connectionType1;
+ }
+ TPtrC8 myDescriptor((const TUint8*)data, size);
+ val = socketHandler->StartWriteDatagram(myDescriptor, port);
+ }
+ END
+
+ return val;
+}
+
+/*!
+ Connection-Less Mode
+*/
+qint64 QLLCPBind::WriteDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ BEGIN
+ Q_UNUSED(target);
+ qint64 val = -1;
+ CLlcpSocketType1* socketHandler = m_socket->socketType1Instance();
+ if (socketHandler != NULL)
+ {
+ TPtrC8 myDescriptor((const TUint8*)data, size);
+ val = socketHandler->StartWriteDatagram(myDescriptor, port);
+ }
+ END
+ return val;
+}
+
+/*!
+ Connection-Oriented Mode - Client side socket write
+*/
+qint64 QLLCPConnected::WriteDatagram(const char *data, qint64 size)
+{
+ BEGIN
+ qint64 val = -1;
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Handler();
+ if (socketHandler != NULL)
+ {
+ TPtrC8 myDescriptor((const TUint8*)data, size);
+ val = socketHandler->StartWriteDatagram(myDescriptor);
+ }
+ END
+ return val;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+bool QLLCPConnected::WaitForBytesWritten(int msecs)
+{
+ BEGIN
+ bool ret = false;
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Handler();
+ if (socketHandler != NULL)
+ {
+ ret = socketHandler->WaitForBytesWritten(msecs);
+ }
+ END
+ return ret;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+bool QLLCPConnected::WaitForReadyRead(int msecs)
+{
+ BEGIN
+ bool ret = false;
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Handler();
+ if (socketHandler != NULL)
+ {
+ ret = socketHandler->WaitForReadyRead(msecs);
+ }
+ END
+ return ret;
+}
+
+/*!
+ Connection-Less Mode
+*/
+qint64 QLLCPBind::ReadDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ BEGIN
+
+ Q_UNUSED(target);
+ qint64 val = -1;
+
+ CLlcpSocketType1* socketHandler = m_socket->socketType1Instance();
+
+ if (socketHandler != NULL)
+ {
+ TPtr8 ptr((TUint8*)data, (TInt)maxSize);
+ if (port == NULL){
+ val = socketHandler->ReadDatagram(ptr);
+ }
+ else {
+ val = socketHandler->ReadDatagram(ptr, *port);
+ }
+ }
+
+ END
+ return val;
+}
+
+
+/*!
+ Connection-Oriented Mode - Client side socket read
+*/
+qint64 QLLCPConnected::ReadDatagram(char *data, qint64 maxSize,QNearFieldTarget **target, quint8 *port )
+{
+ BEGIN
+ qint64 val = -1;
+
+ if ( port != NULL || ( target != NULL && *target != NULL ))
+ {
+ return val;
+ }
+
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Handler();
+ if (socketHandler != NULL)
+ {
+ // The length of the descriptor is set to zero
+ // and its maximum length is set to maxSize
+ TPtr8 ptr((TUint8*)data, (TInt)maxSize);
+
+ bool ret = socketHandler->ReceiveData(ptr);
+ if(ret) {
+ val = ptr.Length();
+ }
+ }
+
+ END
+ return val;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+void QLLCPConnected::DisconnectFromService()
+{
+ BEGIN
+ DisconnectFromServiceType2Private();
+ END
+ return;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+void QLLCPConnecting::DisconnectFromService()
+{
+ BEGIN
+ DisconnectFromServiceType2Private();
+ END
+ return;
+}
+
+void QLLCPSocketState::DisconnectFromServiceType2Private()
+{
+ BEGIN
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Handler();
+ if (NULL != socketHandler)
+ {
+ if (socketHandler->DisconnectFromService() == KErrNone)
+ {
+ m_socket->changeState(m_socket->getUnconnectedState());
+ m_socket->invokeStateChanged(QLlcpSocket::UnconnectedState);
+ }
+ else
+ {
+ m_socket->invokeError();
+ }
+ }
+ else
+ {
+ m_socket->invokeError();
+ }
+ END
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+void QLLCPUnconnected::DisconnectFromService()
+{
+ BEGIN_END
+ return;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+bool QLLCPConnecting::WaitForConnected(int msecs)
+{
+ BEGIN
+ bool ret = false;
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Handler();
+ if (socketHandler != NULL)
+ {
+ ret = socketHandler->WaitForConnected(msecs);
+ }
+ END
+ return ret;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+bool QLLCPConnecting::WaitForBytesWritten(int)
+{
+ return false;
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+void QLLCPUnconnected::ConnectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ BEGIN
+ if (connectionType1 == m_socketType){
+ m_socket->invokeError();
+ END
+ return;
+ }
+
+ CLlcpSocketType2* socketHandler = m_socket->socketType2Instance();
+
+ if (socketHandler != NULL)
+ {
+ if (connectionUnknown == m_socketType)
+ {
+ m_socketType = connectionType2;
+ }
+
+ TRAPD(err, socketHandler->ConnectToServiceL(serviceUri));
+ if (KErrNone == err)
+ {
+ m_socket->changeState(m_socket->getConnectingState());
+ m_socket->invokeStateChanged(QLlcpSocket::ConnectingState);
+ }
+ else
+ {
+ m_socket->invokeError();
+ }
+
+ }
+ else
+ {
+ m_socket->invokeError();
+ }
+
+ END
+}
+
+/*!
+ Connection-Oriented Mode
+*/
+void QLLCPConnecting::ConnectToService(QNearFieldTarget *target, const QString &serviceUri)
+ {
+ Q_UNUSED(target);
+ Q_UNUSED(serviceUri);
+ m_socket->invokeError();
+ qWarning("QLlcpSocket::connectToService() called when already connecting");
+ BEGIN_END
+ return;
+ }
+
+/*!
+ Connection-Oriented Mode
+*/
+void QLLCPConnected::ConnectToService(QNearFieldTarget *target, const QString &serviceUri)
+ {
+ Q_UNUSED(target);
+ Q_UNUSED(serviceUri);
+ m_socket->invokeError();
+ qWarning("QLlcpSocket::connectToService() called when already connected");
+ BEGIN_END
+ return;
+ }
+
+/*!
+ Constructors
+*/
+QLLCPUnconnected::QLLCPUnconnected(QLlcpSocketPrivate* aSocket)
+ :QLLCPSocketState(aSocket),
+ m_socketType(connectionUnknown)
+{}
+
+
+QLLCPBind::QLLCPBind(QLlcpSocketPrivate* aSocket)
+ :QLLCPSocketState(aSocket)
+{}
+
+QLLCPConnecting::QLLCPConnecting(QLlcpSocketPrivate* aSocket)
+ :QLLCPSocketState(aSocket)
+{}
+
+QLLCPConnected::QLLCPConnected(QLlcpSocketPrivate* aSocket)
+ :QLLCPSocketState(aSocket)
+{}
+
+qint64 QLLCPSocketState::ReadDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target, quint8 *port)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxSize);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+ BEGIN_END
+ return -1;
+}
+
+/*!
+ State base class default implementation
+*/
+qint64 QLLCPSocketState::WriteDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(size);
+ Q_UNUSED(target);
+ Q_UNUSED(port);
+ BEGIN_END
+ return -1;
+}
+
+qint64 QLLCPSocketState::WriteDatagram(const char *data, qint64 size)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(size);
+ BEGIN_END
+ return -1;
+}
+
+bool QLLCPSocketState::Bind(quint8 port)
+{
+ Q_UNUSED(port);
+ BEGIN_END
+ return false;
+}
+
+ bool QLLCPSocketState::WaitForReadyRead(int msecs)
+ {
+ Q_UNUSED(msecs);
+ BEGIN_END
+ return false;
+ }
+
+bool QLLCPSocketState::WaitForConnected(int msecs)
+{
+ Q_UNUSED(msecs);
+ BEGIN_END
+ return false;
+}
+
+bool QLLCPSocketState::WaitForDisconnected(int msecs)
+{
+ Q_UNUSED(msecs);
+ BEGIN_END
+ return false;
+}
+
+void QLLCPSocketState::ConnectToService(QNearFieldTarget *target, const QString &serviceUri)
+{
+ Q_UNUSED(target);
+ Q_UNUSED(serviceUri);
+ m_socket->invokeError();
+ BEGIN_END
+}
+
+void QLLCPSocketState::DisconnectFromService()
+{
+ m_socket->invokeError();
+ BEGIN_END
+}
+
diff --git a/src/nfc/qllcpstate_symbian_p.h b/src/nfc/qllcpstate_symbian_p.h
new file mode 100644
index 00000000..38d6bb17
--- /dev/null
+++ b/src/nfc/qllcpstate_symbian_p.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLLCPSOCKETSTATE_P_H
+#define QLLCPSOCKETSTATE_P_H
+
+#include <qconnectivityglobal.h>
+#include "qllcpsocket.h"
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+class QLlcpSocketPrivate;
+
+/*!
+ \QLLCPSocketState
+*/
+class QLLCPSocketState
+{
+public:
+ explicit QLLCPSocketState(QLlcpSocketPrivate*);
+
+public:
+ virtual QLlcpSocket::SocketState state() const = 0;
+ virtual bool WaitForBytesWritten(int) = 0;
+
+public:
+ virtual qint64 ReadDatagram(char *data, qint64 maxSize,
+ QNearFieldTarget **target = NULL, quint8 *port = NULL);
+ virtual qint64 WriteDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ virtual qint64 WriteDatagram(const char *data, qint64 size);
+
+ virtual bool Bind(quint8 port);
+ virtual void ConnectToService(QNearFieldTarget *target, const QString &serviceUri);
+ virtual void DisconnectFromService();
+ virtual bool WaitForReadyRead(int);
+ virtual bool WaitForConnected(int);
+ virtual bool WaitForDisconnected(int);
+
+protected:
+ bool WaitForBytesWrittenType1Private(int);
+ void DisconnectFromServiceType2Private();
+public:
+ QLlcpSocketPrivate* m_socket;
+};
+
+/*!
+ \QLLCPUnconnected
+*/
+class QLLCPUnconnected: public QLLCPSocketState
+{
+public:
+ explicit QLLCPUnconnected(QLlcpSocketPrivate*);
+
+public: // from base class
+ QLlcpSocket::SocketState state() const {return QLlcpSocket::UnconnectedState;}
+ bool Bind(quint8 port);
+ void ConnectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void DisconnectFromService();
+ qint64 WriteDatagram(const char *data, qint64 size,
+ QNearFieldTarget *target, quint8 port);
+ bool WaitForBytesWritten(int);
+ bool WaitForDisconnected(int);
+
+public:
+public:
+ enum SocketType
+ {
+ connectionType1 = 1, // ConnectionLess mode
+ connectionType2 = 2, // ConnectionOriented mode
+ connectionUnknown = -1
+ };
+ SocketType m_socketType;
+};
+
+/*!
+ \QLLCPConnecting
+*/
+class QLLCPConnecting: public QLLCPSocketState
+{
+public:
+ explicit QLLCPConnecting(QLlcpSocketPrivate*);
+
+public:
+ QLLCPSocketState* Instance(QLlcpSocketPrivate* aSocket);
+
+public: // from base class
+ QLlcpSocket::SocketState state() const {return QLlcpSocket::ConnectingState;}
+ void ConnectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void DisconnectFromService();
+ bool WaitForConnected(int);
+ bool WaitForBytesWritten(int);
+};
+
+/*!
+ \QLLCPConnecting
+*/
+class QLLCPConnected: public QLLCPSocketState
+{
+public:
+ explicit QLLCPConnected(QLlcpSocketPrivate*);
+
+public: // from base class
+ QLlcpSocket::SocketState state() const {return QLlcpSocket::ConnectedState;}
+ void ConnectToService(QNearFieldTarget *target, const QString &serviceUri);
+ void DisconnectFromService();
+ qint64 WriteDatagram(const char *data, qint64 size);
+ qint64 ReadDatagram(char *data, qint64 maxSize, QNearFieldTarget **target = NULL, quint8 *port = NULL);
+ bool WaitForBytesWritten(int msecs);
+ bool WaitForReadyRead(int msecs);
+};
+
+/*!
+ \QLLCPBind
+*/
+class QLLCPBind: public QLLCPSocketState
+ {
+public:
+ explicit QLLCPBind(QLlcpSocketPrivate*);
+
+public://from base class
+ QLlcpSocket::SocketState state() const {return QLlcpSocket::BoundState;}
+ qint64 WriteDatagram(const char *data, qint64 size,QNearFieldTarget *target, quint8 port);
+ qint64 ReadDatagram(char *data, qint64 maxSize,QNearFieldTarget **target = 0, quint8 *port = 0);
+ bool WaitForBytesWritten(int msecs);
+ bool WaitForReadyRead(int msecs);
+ };
+
+QT_END_HEADER
+
+#endif //QLLCPSTATE_P_H
diff --git a/src/nfc/qndeffilter.cpp b/src/nfc/qndeffilter.cpp
new file mode 100644
index 00000000..ce25c4ab
--- /dev/null
+++ b/src/nfc/qndeffilter.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qndeffilter.h"
+
+#include <QtCore/QList>
+
+/*!
+ \class QNdefFilter
+ \brief The QNdefFilter class provides a filter for matching NDEF messages.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ The QNdefFilter encapsulates the structure of an NDEF message and is used by
+ QNearFieldManager::registerNdefMessageHandler() to match NDEF message that have a particular
+ structure.
+
+ The following filter matches NDEF messages that contain a single smart poster record:
+
+ \code
+ QNdefFilter filter;
+ filter.append(QNdefRecord::NfcRtd, "Sp");
+ \endcode
+
+ The following filter matches NDEF messages that contain a URI, a localized piece of text and an
+ optional JPEG image. The order of the records must be in the order specified:
+
+ \code
+ QNdefFilter filter;
+ filter.setOrderMatch(true);
+ filter.appendRecord(QNdefRecord::NfcRtd, "U");
+ filter.appendRecord<QNdefNfcTextRecord>();
+ filter.appendRecord(QNdefRecord::Mime, "image/jpeg", 0, 1);
+ \endcode
+*/
+
+/*!
+ \fn void QNdefFilter::appendRecord(unsigned int min, unsigned int max)
+
+ Appends a record matching the template parameter to the NDEF filter. The record must occur
+ between \a min and \a max times in the NDEF message.
+*/
+
+class QNdefFilterPrivate : public QSharedData
+{
+public:
+ QNdefFilterPrivate();
+
+ bool orderMatching;
+ QList<QNdefFilter::Record> filterRecords;
+};
+
+QNdefFilterPrivate::QNdefFilterPrivate()
+: orderMatching(false)
+{
+}
+
+/*!
+ Constructs a new NDEF filter.
+*/
+QNdefFilter::QNdefFilter()
+: d(new QNdefFilterPrivate)
+{
+}
+
+/*!
+ constructs a new NDEF filter that is a copy of \a other.
+*/
+QNdefFilter::QNdefFilter(const QNdefFilter &other)
+: d(other.d)
+{
+}
+
+/*!
+ Destroys the NDEF filter.
+*/
+QNdefFilter::~QNdefFilter()
+{
+}
+
+/*!
+ Assigns \a other to this filter and returns a reference to this filter.
+*/
+QNdefFilter &QNdefFilter::operator=(const QNdefFilter &other)
+{
+ if (d != other.d)
+ d = other.d;
+
+ return *this;
+}
+
+/*!
+ Clears the filter.
+*/
+void QNdefFilter::clear()
+{
+ d->orderMatching = false;
+ d->filterRecords.clear();
+}
+
+/*!
+ Sets the ording requirements of the filter. If \a on is true the filter will only match if the
+ order of records in the filter matches the order of the records in the NDEF message. If \a on
+ is false the order of the records is not taken into account when matching.
+
+ By default record order is not taken into account.
+*/
+void QNdefFilter::setOrderMatch(bool on)
+{
+ d->orderMatching = on;
+}
+
+/*!
+ Returns true if the filter takes NDEF record order into account when matching; otherwise
+ returns false.
+*/
+bool QNdefFilter::orderMatch() const
+{
+ return d->orderMatching;
+}
+
+/*!
+ Appends a record with type name format \a typeNameFormat and type \a type to the NDEF filter.
+ The record must occur between \a min and \a max times in the NDEF message.
+*/
+void QNdefFilter::appendRecord(QNdefRecord::TypeNameFormat typeNameFormat, const QByteArray &type,
+ unsigned int min, unsigned int max)
+{
+ QNdefFilter::Record record;
+
+ record.typeNameFormat = typeNameFormat;
+ record.type = type;
+ record.minimum = min;
+ record.maximum = max;
+
+ d->filterRecords.append(record);
+}
+
+/*!
+ Appends \a record to the NDEF filter.
+*/
+void QNdefFilter::appendRecord(const Record &record)
+{
+ d->filterRecords.append(record);
+}
+
+/*!
+ Returns the NDEF record at index \a i.
+*/
+QNdefFilter::Record QNdefFilter::recordAt(int i) const
+{
+ return d->filterRecords.at(i);
+}
+
+/*!
+ Returns the number of NDEF records in the filter.
+*/
+int QNdefFilter::recordCount() const
+{
+ return d->filterRecords.count();
+}
+
diff --git a/src/nfc/qndeffilter.h b/src/nfc/qndeffilter.h
new file mode 100644
index 00000000..5cc92863
--- /dev/null
+++ b/src/nfc/qndeffilter.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNDEFFILTER_H
+#define QNDEFFILTER_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QSharedDataPointer>
+
+#include <qndefrecord.h>
+
+QT_BEGIN_HEADER
+
+class QNdefFilterPrivate;
+class Q_CONNECTIVITY_EXPORT QNdefFilter
+{
+public:
+ QNdefFilter();
+ QNdefFilter(const QNdefFilter &other);
+ ~QNdefFilter();
+
+ void clear();
+
+ void setOrderMatch(bool on);
+ bool orderMatch() const;
+
+ struct Record {
+ QNdefRecord::TypeNameFormat typeNameFormat;
+ QByteArray type;
+ unsigned int minimum;
+ unsigned int maximum;
+ };
+
+ template<typename T>
+ void appendRecord(unsigned int min = 1, unsigned int max = 1);
+ void appendRecord(QNdefRecord::TypeNameFormat typeNameFormat, const QByteArray &type,
+ unsigned int min = 1, unsigned int max = 1);
+ void appendRecord(const Record &record);
+
+ int recordCount() const;
+ Record recordAt(int i) const;
+
+ QNdefFilter &operator=(const QNdefFilter &other);
+
+private:
+ QSharedDataPointer<QNdefFilterPrivate> d;
+};
+
+template <typename T>
+void QNdefFilter::appendRecord(unsigned int min, unsigned int max)
+{
+ T record;
+
+ appendRecord(record.typeNameFormat(), record.type(), min, max);
+}
+
+QT_END_HEADER
+
+#endif // QNDEFFILTER_H
diff --git a/src/nfc/qndefmessage.cpp b/src/nfc/qndefmessage.cpp
new file mode 100644
index 00000000..532e8bff
--- /dev/null
+++ b/src/nfc/qndefmessage.cpp
@@ -0,0 +1,319 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qndefmessage.h"
+#include "qndefrecord_p.h"
+
+/*!
+ \class QNdefMessage
+ \brief The QNdefMessage class provides an NFC NDEF message.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ A QNdefMessage is a collection of 0 or more QNdefRecords. QNdefMessage inherits from
+ QList<QNdefRecord> and therefore the standard QList functions can be used to manipulate the
+ NDEF records in the message.
+
+ NDEF messages can be parsed from a byte array conforming to the NFC Data Exchange Format
+ technical specification by using the fromByteArray() static function. Conversely QNdefMessages
+ can be converted into a byte array with the toByteArray() function.
+*/
+
+/*!
+ \fn QNdefMessage::QNdefMessage()
+
+ Constructs a new empty NDEF message.
+*/
+
+/*!
+ \fn QNdefMessage::QNdefMessage(const QNdefRecord &record)
+
+ Constructs a new NDEF message containing a single record \a record.
+*/
+
+/*!
+ \fn QNdefMessage::QNdefMessage(const QNdefMessage &message)
+
+ Constructs a new NDEF message that is a copy of \a message.
+*/
+
+/*!
+ \fn QNdefMessage::QNdefMessage(const QList<QNdefRecord> &records)
+
+ Constructs a new NDEF message that contains all of the records in \a records.
+*/
+
+/*!
+ Returns an NDEF message parsed from the contents of \a message.
+
+ The \a message parameter is interpreted as the raw message format defined in the NFC Data
+ Exchange Format technical specification.
+
+ If a parse error occurs an empty NDEF message is returned.
+*/
+QNdefMessage QNdefMessage::fromByteArray(const QByteArray &message)
+{
+ QNdefMessage result;
+
+ bool seenMessageBegin = false;
+ bool seenMessageEnd = false;
+
+ QByteArray partialChunk;
+ QNdefRecord record;
+
+ QByteArray::const_iterator i = message.begin();
+ while (i < message.constEnd()) {
+ quint8 flags = *i;
+
+ bool messageBegin = flags & 0x80;
+ bool messageEnd = flags & 0x40;
+
+ bool cf = flags & 0x20;
+ bool sr = flags & 0x10;
+ bool il = flags & 0x08;
+ quint8 typeNameFormat = flags & 0x07;
+
+ if (messageBegin && seenMessageBegin) {
+ qWarning("Got message begin but already parsed some records");
+ return QNdefMessage();
+ } else if (!messageBegin && !seenMessageBegin) {
+ qWarning("Haven't got message begin yet");
+ return QNdefMessage();
+ } else if (messageBegin && !seenMessageBegin) {
+ seenMessageBegin = true;
+ }
+ if (messageEnd && seenMessageEnd) {
+ qWarning("Got message end but already parsed final record");
+ return QNdefMessage();
+ } else if (messageEnd && !seenMessageEnd) {
+ seenMessageEnd = true;
+ }
+ if (cf && (typeNameFormat != 0x06) && !partialChunk.isEmpty()) {
+ qWarning("partial chunk not empty or typeNameFormat not 0x06 as expected");
+ return QNdefMessage();
+ }
+
+ int headerLength = 1;
+ headerLength += (sr) ? 1 : 4;
+ headerLength += (il) ? 1 : 0;
+
+ if (i + headerLength >= message.constEnd()) {
+ qWarning("Unexpected end of message");
+ return QNdefMessage();
+ }
+
+ quint8 typeLength = *(++i);
+
+ if ((typeNameFormat == 0x06) && (typeLength != 0)) {
+ qWarning("Invalid chunked data, TYPE_LENGTH != 0");
+ return QNdefMessage();
+ }
+
+ quint32 payloadLength;
+ if (sr)
+ payloadLength = *(++i);
+ else {
+ payloadLength = quint8(*(++i)) << 24;
+ payloadLength |= quint8(*(++i)) << 16;
+ payloadLength |= quint8(*(++i)) << 8;
+ payloadLength |= quint8(*(++i)) << 0;
+ }
+
+ quint8 idLength;
+ if (il)
+ idLength = *(++i);
+ else
+ idLength = 0;
+
+ int contentLength = typeLength + payloadLength + idLength;
+ if (i + contentLength >= message.constEnd()) {
+ qWarning("Unexpected end of message");
+ return QNdefMessage();
+ }
+
+ if ((typeNameFormat == 0x06) && (idLength != 0)) {
+ qWarning("Invalid chunked data, IL != 0");
+ return QNdefMessage();
+ }
+
+ if (typeNameFormat != 0x06)
+ record.setTypeNameFormat(QNdefRecord::TypeNameFormat(typeNameFormat));
+
+ if (typeLength > 0) {
+ QByteArray type(++i, typeLength);
+ record.setType(type);
+ i += typeLength - 1;
+ }
+
+ if (idLength > 0) {
+ QByteArray id(++i, idLength);
+ record.setId(id);
+ i += idLength - 1;
+ }
+
+ if (payloadLength > 0) {
+ QByteArray payload(++i, payloadLength);
+
+
+ if (cf) {
+ // chunked payload, except last
+ partialChunk.append(payload);
+ } else if (typeNameFormat == 0x06) {
+ // last chunk of chunked payload
+ record.setPayload(partialChunk + payload);
+ partialChunk.clear();
+ } else {
+ // non-chunked payload
+ record.setPayload(payload);
+ }
+
+ i += payloadLength - 1;
+ }
+
+ if (!cf)
+ result.append(record);
+
+ if (!cf && seenMessageEnd)
+ break;
+
+ // move to start of next record
+ ++i;
+ }
+
+ if (!seenMessageBegin && !seenMessageEnd) {
+ qWarning("Malformed NDEF Message, missing begin or end.");
+ return QNdefMessage();
+ }
+
+ return result;
+}
+
+/*!
+ Returns true if this NDEF message is equivalent to \a other; otherwise returns false.
+
+ An empty message (i.e. isEmpty() returns true) is equivalent to a NDEF message containing a
+ single record of type QNdefRecord::Empty.
+*/
+bool QNdefMessage::operator==(const QNdefMessage &other) const
+{
+ // both records are empty
+ if (isEmpty() && other.isEmpty())
+ return true;
+
+ // compare empty to really empty
+ if (isEmpty() && other.count() == 1 && other.first().typeNameFormat() == QNdefRecord::Empty)
+ return true;
+ if (other.isEmpty() && count() == 1 && first().typeNameFormat() == QNdefRecord::Empty)
+ return true;
+
+ if (count() != other.count())
+ return false;
+
+ for (int i = 0; i < count(); ++i) {
+ if (at(i) != other.at(i))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns the NDEF message as a byte array.
+
+ The return value of this function conforms to the format defined in the NFC Data Exchange
+ Format technical specification.
+*/
+QByteArray QNdefMessage::toByteArray() const
+{
+ // An empty message is treated as a message containing a single empty record.
+ if (isEmpty())
+ return QNdefMessage(QNdefRecord()).toByteArray();
+
+ QByteArray m;
+
+ for (int i = 0; i < count(); ++i) {
+ const QNdefRecord &record = at(i);
+
+ quint8 flags = record.typeNameFormat();
+
+ if (i == 0)
+ flags |= 0x80;
+ if (i == count() - 1)
+ flags |= 0x40;
+
+ // cf (chunked records) not supported yet
+
+ if (record.payload().length() < 255)
+ flags |= 0x10;
+
+ if (!record.id().isEmpty())
+ flags |= 0x08;
+
+ m.append(flags);
+ m.append(record.type().length());
+
+ if (flags & 0x10) {
+ m.append(quint8(record.payload().length()));
+ } else {
+ quint32 length = record.payload().length();
+ m.append(length >> 24);
+ m.append(length >> 16);
+ m.append(length >> 8);
+ m.append(length & 0x000000ff);
+ }
+
+ if (flags & 0x08)
+ m.append(record.id().length());
+
+ if (!record.type().isEmpty())
+ m.append(record.type());
+
+ if (!record.id().isEmpty())
+ m.append(record.id());
+
+ if (!record.payload().isEmpty())
+ m.append(record.payload());
+ }
+
+ return m;
+}
diff --git a/src/nfc/qndefmessage.h b/src/nfc/qndefmessage.h
new file mode 100644
index 00000000..e6aef623
--- /dev/null
+++ b/src/nfc/qndefmessage.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNDEFMESSAGE_H
+#define QNDEFMESSAGE_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <qndefrecord.h>
+
+#include <QtCore/QVector>
+#include <QtCore/QSet>
+#include <QtCore/QList>
+#include <QtCore/QMetaType>
+
+QT_BEGIN_HEADER
+
+class Q_CONNECTIVITY_EXPORT QNdefMessage : public QList<QNdefRecord>
+{
+public:
+ inline QNdefMessage() { }
+ inline explicit QNdefMessage(const QNdefRecord &record) { append(record); }
+ inline QNdefMessage(const QNdefMessage &message) : QList<QNdefRecord>(message) { }
+ inline QNdefMessage(const QList<QNdefRecord> &records) : QList<QNdefRecord>(records) { }
+
+ bool operator==(const QNdefMessage &other) const;
+
+ QByteArray toByteArray() const;
+
+ static QNdefMessage fromByteArray(const QByteArray &message);
+};
+
+Q_DECLARE_METATYPE(QNdefMessage)
+
+QT_END_HEADER
+
+#endif // QNDEFMESSAGE_H
diff --git a/src/nfc/qndefnfctextrecord.cpp b/src/nfc/qndefnfctextrecord.cpp
new file mode 100644
index 00000000..b9146f9a
--- /dev/null
+++ b/src/nfc/qndefnfctextrecord.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qndefnfctextrecord.h>
+
+#include <QtCore/QTextCodec>
+#include <QtCore/QLocale>
+
+/*!
+ \class QNdefNfcTextRecord
+ \brief The QNdefNfcTextRecord class provides an NFC RTD-Text
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ RTD-Text encapsulates a user displayable text record.
+*/
+
+/*!
+ \enum QNdefNfcTextRecord::Encoding
+
+ This enum describes the text encoding standard used.
+
+ \value Utf8 The text is encoded with UTF-8.
+ \value Utf16 The text is encoding with UTF-16.
+*/
+
+/*!
+ Returns the locale of the text record.
+*/
+QString QNdefNfcTextRecord::locale() const
+{
+ const QByteArray p = payload();
+
+ if (p.isEmpty())
+ return QString();
+
+ quint8 status = p.at(0);
+
+ quint8 codeLength = status & 0x3f;
+
+ return QString::fromAscii(p.constData() + 1, codeLength);
+}
+
+/*!
+ Sets the locale of the text record to \a locale.
+*/
+void QNdefNfcTextRecord::setLocale(const QString &locale)
+{
+ QByteArray p = payload();
+
+ quint8 status = p.isEmpty() ? 0 : p.at(0);
+
+ quint8 codeLength = status & 0x3f;
+
+ quint8 newStatus = (status & 0xd0) | locale.length();
+
+ p[0] = newStatus;
+ p.replace(1, codeLength, locale.toAscii());
+
+ setPayload(p);
+}
+
+/*!
+ Returns the contents of the text record as a string.
+*/
+QString QNdefNfcTextRecord::text() const
+{
+ const QByteArray p = payload();
+
+ if (p.isEmpty())
+ return QString();
+
+ quint8 status = p.at(0);
+
+ bool utf16 = status & 0x80;
+ quint8 codeLength = status & 0x3f;
+
+ QTextCodec *codec = QTextCodec::codecForName(utf16 ? "UTF-16BE" : "UTF-8");
+
+ return codec->toUnicode(p.constData() + 1 + codeLength, p.length() - 1 - codeLength);
+}
+
+/*!
+ Sets the contents of the text record to \a text.
+*/
+void QNdefNfcTextRecord::setText(const QString text)
+{
+ if (payload().isEmpty())
+ setLocale(QLocale().name());
+
+ QByteArray p = payload();
+
+ quint8 status = p.at(0);
+
+ bool utf16 = status & 0x80;
+ quint8 codeLength = status & 0x3f;
+
+ p.truncate(1 + codeLength);
+
+ QTextCodec *codec = QTextCodec::codecForName(utf16 ? "UTF-16BE" : "UTF-8");
+
+ p += codec->fromUnicode(text);
+
+ setPayload(p);
+}
+
+/*!
+ Returns the encoding of the contents.
+*/
+QNdefNfcTextRecord::Encoding QNdefNfcTextRecord::encoding() const
+{
+ if (payload().isEmpty())
+ return Utf8;
+
+ QByteArray p = payload();
+
+ quint8 status = p.at(0);
+
+ bool utf16 = status & 0x80;
+
+ if (utf16)
+ return Utf16;
+ else
+ return Utf8;
+}
+
+/*!
+ Sets the enconding of the contents to \a encoding.
+*/
+void QNdefNfcTextRecord::setEncoding(Encoding encoding)
+{
+ QByteArray p = payload();
+
+ quint8 status = p.isEmpty() ? 0 : p.at(0);
+
+ QString string = text();
+
+ if (encoding == Utf8)
+ status &= ~0x80;
+ else
+ status |= 0x80;
+
+ p[0] = status;
+
+ setPayload(p);
+
+ setText(string);
+}
+
diff --git a/src/nfc/qndefnfctextrecord.h b/src/nfc/qndefnfctextrecord.h
new file mode 100644
index 00000000..2333e3ff
--- /dev/null
+++ b/src/nfc/qndefnfctextrecord.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNDEFNFCTEXTRECORD_H
+#define QNDEFNFCTEXTRECORD_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <qndefrecord.h>
+
+QT_BEGIN_HEADER
+
+class Q_CONNECTIVITY_EXPORT QNdefNfcTextRecord : public QNdefRecord
+{
+public:
+ Q_DECLARE_NDEF_RECORD(QNdefNfcTextRecord, QNdefRecord::NfcRtd, "T", QByteArray(1, char(0)))
+
+ QString locale() const;
+ void setLocale(const QString &locale);
+
+ QString text() const;
+ void setText(const QString text);
+
+ enum Encoding {
+ Utf8,
+ Utf16
+ };
+
+ Encoding encoding() const;
+ void setEncoding(Encoding encoding);
+};
+
+Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(QNdefNfcTextRecord, QNdefRecord::NfcRtd, "T")
+
+QT_END_HEADER
+
+#endif // QNDEFNFCTEXTRECORD_H
diff --git a/src/nfc/qndefnfcurirecord.cpp b/src/nfc/qndefnfcurirecord.cpp
new file mode 100644
index 00000000..4a495d2d
--- /dev/null
+++ b/src/nfc/qndefnfcurirecord.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qndefnfcurirecord.h"
+
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+
+#include <QtCore/QDebug>
+
+/*!
+ \class QNdefNfcUriRecord
+ \brief The QNdefNfcUriRecord class provides an NFC RTD-URI
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ RTD-URI encapsulates a URI.
+*/
+
+static const char * const abbreviations[] = {
+ 0,
+ "http://www.",
+ "https://www.",
+ "http://",
+ "https://",
+ "tel:",
+ "mailto:",
+ "ftp://anonymous:anonymous@",
+ "ftp://ftp.",
+ "ftps://",
+ "sftp://",
+ "smb://",
+ "nfs://",
+ "ftp://",
+ "dav://",
+ "news:",
+ "telnet://",
+ "imap:",
+ "rtsp://",
+ "urn:",
+ "pop:",
+ "sip:",
+ "sips:",
+ "tftp:",
+ "btspp://",
+ "btl2cap://",
+ "btgoep://",
+ "tcpobex://",
+ "irdaobex://",
+ "file://",
+ "urn:epc:id:",
+ "urn:epc:tag:",
+ "urn:epc:pat:",
+ "urn:epc:raw:",
+ "urn:epc:",
+ "urn:nfc:",
+};
+
+/*!
+ Returns the URI of this URI record.
+*/
+QUrl QNdefNfcUriRecord::uri() const
+{
+ const QByteArray p = payload();
+
+ if (p.isEmpty())
+ return QUrl();
+
+ quint8 code = p.at(0);
+ if (code >= sizeof(abbreviations) / sizeof(*abbreviations))
+ code = 0;
+
+ return QUrl(QLatin1String(abbreviations[code]) + QString::fromUtf8(p.mid(1), p.length() - 1));
+}
+
+/*!
+ Sets the URI of this URI record to \a uri.
+*/
+void QNdefNfcUriRecord::setUri(const QUrl &uri)
+{
+ int abbrevs = sizeof(abbreviations) / sizeof(*abbreviations);
+
+ for (int i = 1; i < abbrevs; ++i) {
+ if (uri.toString().startsWith(QLatin1String(abbreviations[i]))) {
+ QByteArray p;
+
+ p[0] = i;
+ p += uri.toString().mid(qstrlen(abbreviations[i])).toUtf8();
+
+ setPayload(p);
+
+ return;
+ }
+ }
+
+ QByteArray p;
+ p[0] = 0;
+ p += uri.toString().toUtf8();
+
+ setPayload(p);
+}
+
diff --git a/src/nfc/qndefnfcurirecord.h b/src/nfc/qndefnfcurirecord.h
new file mode 100644
index 00000000..10bddff7
--- /dev/null
+++ b/src/nfc/qndefnfcurirecord.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNDEFNFCURIRECORD_H
+#define QNDEFNFCURIRECORD_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <qndefrecord.h>
+
+QT_FORWARD_DECLARE_CLASS(QUrl)
+
+QT_BEGIN_HEADER
+
+class Q_CONNECTIVITY_EXPORT QNdefNfcUriRecord : public QNdefRecord
+{
+public:
+ Q_DECLARE_NDEF_RECORD(QNdefNfcUriRecord, QNdefRecord::NfcRtd, "U", QByteArray(0, char(0)))
+
+ QUrl uri() const;
+ void setUri(const QUrl &uri);
+};
+
+Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(QNdefNfcUriRecord, QNdefRecord::NfcRtd, "U")
+
+QT_END_HEADER
+
+#endif // QNDEFNFCURIRECORD_H
diff --git a/src/nfc/qndefrecord.cpp b/src/nfc/qndefrecord.cpp
new file mode 100644
index 00000000..4db78e2b
--- /dev/null
+++ b/src/nfc/qndefrecord.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qndefrecord.h"
+#include "qndefrecord_p.h"
+
+#include <QtCore/QHash>
+
+/*!
+ \class QNdefRecord
+ \brief The QNdefRecord class provides an NFC NDEF record.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ QNdefRecord and derived classes are used to parse the contents of
+ \l {QNdefMessage}{NDEF messages} and create new NDEF messages.
+
+ Use typeNameFormat(), userTypeNameFormat(), setTypeNameFormat() and setUserTypeNameFormat() to
+ get and set the type name format of the NDEF record.
+
+ Use type() and setType() to get and set the type of the NDEF record.
+
+ Use id() and setId() to get and set the id of the NDEF record.
+
+ Use payload() and setPayload() to get and set the NDEF record payload. isEmpty() can be used
+ to test if the payload is empty.
+
+ QNdefRecord is an implicitly shared class. This means you can efficiently convert between
+ QNdefRecord and specialized record classes. The isRecordType() template function can be used
+ to test if a conversion is possible. The following example shows how to test if a QNdefRecord
+ is an NFC RTD Text record and extract the text information from it.
+
+ \snippet snippets/connectivity/nfc.cpp Record conversion
+
+ \section1 Creating specialized NDEF record classes
+
+ Specialized NDEF record classes can be easily created with the Q_DECLARE_NDEF_RECORD() and
+ Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD() macros. The following example shows the class
+ declaration of the hypothetical \i {example.com:f} record type that encapsulates a single int
+ property foo.
+
+ \snippet snippets/connectivity/nfc.cpp Specialized class definition
+
+ The developer only needs to provide implementations for the \c {foo()} and \c {setFoo()}
+ functions that parse and set the contents of the NDEF record's payload.
+*/
+
+/*!
+ \enum QNdefRecord::TypeNameFormat
+
+ This enum describes the type name format of an NDEF record.
+
+ \value Empty An empty NDEF record, the record does not contain a payload
+ \value NfcRtd The NDEF record type is defined by an NFC RTD Specification
+ \value Mime The NDEF record type follows the construct described in RFC 2046
+ \value Uri The NDEF record type follows the construct described in RFC 3986
+ \value ExternalRtd The NDEF record type follows the construct for external type names
+ described the NFC RTD Specification
+ \value Unknown The type of the record is unknown and should be treated similar to content
+ with MIME type 'application/octet-stream' without further context
+*/
+
+/*!
+ \fn bool QNdefRecord::isRecordType() const
+
+ Returns true if the NDEF record is of the specified record type; otherwise returns false.
+*/
+
+/*!
+ \fn bool QNdefRecord::operator!=(const QNdefRecord &other) const
+
+ Returns true if this NDEF record does not equal \a other; otherwise return false.
+*/
+
+/*!
+ \macro Q_DECLARE_NDEF_RECORD(className, typeNameFormat, type, initialPayload)
+ \relates QNdefRecord
+
+ This macro declares default and copy constructors for specialized NDEF record classes.
+
+ \a className is the name of the specialized class, \a typeNameFormat is the appropriate
+ QNdefRecord::TypeNameFormat for the custom type and \a type is the type without the NID or NSS
+ prefixes. That is \i {example.com:f} not \i {urn:nfc:ext:example.com:f}. \a initialPayload
+ is the initial payload of an empty record, it must be a QByteArray or a type that can be
+ implicitly converted into a QByteArray.
+
+ See the section on \l {Creating specialized NDEF record classes} for details.
+
+ \sa Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD()
+*/
+
+/*!
+ \macro Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(className, typeNameFormat, type)
+ \relates QNdefRecord
+
+ This macro declares a template specialization for the QNdefRecord::isRecordType() function.
+
+ This macro should be used in the header file directly after the definition of a specialized
+ NDEF record class.
+
+ \a className is the name of the specialized class, \a typeNameFormat is the appropriate
+ QNdefRecord::TypeNameFormat for the custom type and \a type is the type without the NID or NSS
+ prefixes. That is \i {example.com:f} not \i {urn:nfc:ext:example.com:f}.
+
+ See the secton on \l {Creating specialized NDEF record classes} for details.
+
+ \sa Q_DECLARE_NDEF_RECORD()
+*/
+
+uint qHash(const QNdefRecord &key)
+{
+ return qHash(key.type() + key.id() + key.payload());
+}
+
+/*!
+ Constructs a new empty NDEF record.
+*/
+QNdefRecord::QNdefRecord()
+{
+}
+
+/*!
+ Constructs a new NDEF record that is a copy of \a other.
+*/
+QNdefRecord::QNdefRecord(const QNdefRecord &other)
+{
+ d = other.d;
+}
+
+/*!
+ \internal
+
+ Constructs an NDEF record that is a copy of \a other if \a other is of the expected type name
+ format identified by \a typeNameFormat and type as identified by \a type; otherwise an empty
+ NDEF record of the expected type name format and type is created.
+*/
+QNdefRecord::QNdefRecord(const QNdefRecord &other, TypeNameFormat typeNameFormat,
+ const QByteArray &type)
+{
+ if (other.d->typeNameFormat == quint8(typeNameFormat) && other.d->type == type) {
+ d = other.d;
+ } else {
+ d = new QNdefRecordPrivate;
+ d->typeNameFormat = typeNameFormat;
+ d->type = type;
+ }
+}
+
+/*!
+ \internal
+
+ Constructs an NDEF record with a type name format identified by \a typeNameFormat and type as
+ identified by \a type.
+*/
+QNdefRecord::QNdefRecord(TypeNameFormat typeNameFormat, const QByteArray &type)
+: d(new QNdefRecordPrivate)
+{
+ d->typeNameFormat = typeNameFormat;
+ d->type = type;
+}
+
+/*!
+ Destroys the NDEF record.
+*/
+QNdefRecord::~QNdefRecord()
+{
+}
+
+/*!
+ Assigns this NDEF record to \a other.
+*/
+QNdefRecord &QNdefRecord::operator=(const QNdefRecord &other)
+{
+ if (this != &other)
+ d = other.d;
+
+ return *this;
+}
+
+/*!
+ Sets the type name format of the NDEF record to \a typeNameFormat.
+*/
+void QNdefRecord::setTypeNameFormat(TypeNameFormat typeNameFormat)
+{
+ if (!d)
+ d = new QNdefRecordPrivate;
+
+ d->typeNameFormat = typeNameFormat;
+}
+
+/*!
+ Returns the type name format of the NDEF record.
+*/
+QNdefRecord::TypeNameFormat QNdefRecord::typeNameFormat() const
+{
+ if (!d)
+ return Empty;
+
+ if (d->typeNameFormat > 0x05)
+ return Unknown;
+
+ return TypeNameFormat(d->typeNameFormat);
+}
+
+/*!
+ Sets the type of the NDEF record to \a type.
+*/
+void QNdefRecord::setType(const QByteArray &type)
+{
+ if (!d)
+ d = new QNdefRecordPrivate;
+
+ d->type = type;
+}
+
+/*!
+ Returns the type of the NDEF record.
+*/
+QByteArray QNdefRecord::type() const
+{
+ if (!d)
+ return QByteArray();
+
+ return d->type;
+}
+
+/*!
+ Sets the id of the NDEF record to \a id.
+*/
+void QNdefRecord::setId(const QByteArray &id)
+{
+ if (!d)
+ d = new QNdefRecordPrivate;
+
+ d->id = id;
+}
+
+/*!
+ Returns the id of the NDEF record.
+*/
+QByteArray QNdefRecord::id() const
+{
+ if (!d)
+ return QByteArray();
+
+ return d->id;
+}
+
+/*!
+ Sets the payload of the NDEF record to \a payload.
+*/
+void QNdefRecord::setPayload(const QByteArray &payload)
+{
+ if (!d)
+ d = new QNdefRecordPrivate;
+
+ d->payload = payload;
+}
+
+/*!
+ Returns the payload of the NDEF record.
+*/
+QByteArray QNdefRecord::payload() const
+{
+ if (!d)
+ return QByteArray();
+
+ return d->payload;
+}
+
+/*!
+ Returns true if the NDEF record contains an empty payload; otherwise return false.
+
+ This is equivalent to calling \c {payload().isEmpty()}.
+*/
+bool QNdefRecord::isEmpty() const
+{
+ if (!d)
+ return true;
+
+ return d->payload.isEmpty();
+}
+
+/*!
+ Returns true if \a other and this NDEF record are the same.
+*/
+bool QNdefRecord::operator==(const QNdefRecord &other) const
+{
+ if (d == other.d)
+ return true;
+
+ if (!d || !other.d)
+ return false;
+
+ if (d->typeNameFormat != other.d->typeNameFormat)
+ return false;
+
+ if (d->type != other.d->type)
+ return false;
+
+ if (d->id != other.d->id)
+ return false;
+
+ if (d->payload != other.d->payload)
+ return false;
+
+ return true;
+}
diff --git a/src/nfc/qndefrecord.h b/src/nfc/qndefrecord.h
new file mode 100644
index 00000000..31d0e94c
--- /dev/null
+++ b/src/nfc/qndefrecord.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNDEFRECORD_H
+#define QNDEFRECORD_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QByteArray>
+
+QT_BEGIN_HEADER
+
+class QNdefRecordPrivate;
+
+class Q_CONNECTIVITY_EXPORT QNdefRecord
+{
+public:
+ enum TypeNameFormat {
+ Empty = 0x00,
+ NfcRtd = 0x01,
+ Mime = 0x02,
+ Uri = 0x03,
+ ExternalRtd = 0x04,
+ Unknown = 0x05
+ };
+
+ QNdefRecord();
+ ~QNdefRecord();
+
+ QNdefRecord(const QNdefRecord &other);
+ QNdefRecord &operator=(const QNdefRecord &other);
+
+ void setTypeNameFormat(TypeNameFormat typeNameFormat);
+ TypeNameFormat typeNameFormat() const;
+
+ void setType(const QByteArray &type);
+ QByteArray type() const;
+
+ void setId(const QByteArray &id);
+ QByteArray id() const;
+
+ void setPayload(const QByteArray &payload);
+ QByteArray payload() const;
+
+ bool isEmpty() const;
+
+ template <typename T>
+ inline bool isRecordType() const
+ {
+ T dummy;
+ return (typeNameFormat() == dummy.typeNameFormat() && type() == dummy.type());
+ }
+
+ bool operator==(const QNdefRecord &other) const;
+ inline bool operator!=(const QNdefRecord &other) const { return !operator==(other); }
+
+protected:
+ QNdefRecord(const QNdefRecord &other, TypeNameFormat typeNameFormat, const QByteArray &type);
+ QNdefRecord(TypeNameFormat typeNameFormat, const QByteArray &type);
+
+private:
+ QSharedDataPointer<QNdefRecordPrivate> d;
+};
+
+#define Q_DECLARE_NDEF_RECORD(className, typeNameFormat, type, initialPayload) \
+ className() : QNdefRecord(typeNameFormat, type) { setPayload(initialPayload); } \
+ className(const QNdefRecord &other) : QNdefRecord(other, typeNameFormat, type) { }
+
+#define Q_DECLARE_ISRECORDTYPE_FOR_NDEF_RECORD(className, typeNameFormat_, type_) \
+ template<> inline bool QNdefRecord::isRecordType<className>() const\
+ { \
+ return (typeNameFormat() == typeNameFormat_ && type() == type_); \
+ }
+
+uint qHash(const QNdefRecord &key);
+
+QT_END_HEADER
+
+#endif // QNDEFRECORD_H
diff --git a/src/nfc/qndefrecord_p.h b/src/nfc/qndefrecord_p.h
new file mode 100644
index 00000000..ff279d68
--- /dev/null
+++ b/src/nfc/qndefrecord_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QNDEFRECORD_P_H
+#define QNDEFRECORD_P_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QByteArray>
+
+class QNdefRecordPrivate : public QSharedData
+{
+public:
+ //bool messageBegin : 1;
+ //bool messageEnd : 1;
+ unsigned int typeNameFormat : 3;
+
+ QByteArray type;
+ QByteArray id;
+ QByteArray payload;
+};
+
+#endif // QNDEFRECORD_P_H
diff --git a/src/nfc/qnearfieldllcpdevice_symbian.cpp b/src/nfc/qnearfieldllcpdevice_symbian.cpp
new file mode 100644
index 00000000..38f9968c
--- /dev/null
+++ b/src/nfc/qnearfieldllcpdevice_symbian.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldllcpdevice_symbian_p.h"
+
+QNearFieldLlcpDeviceSymbian::QNearFieldLlcpDeviceSymbian(RNfcServer& nfcServer, QObject *parent)
+ : QNearFieldTarget(parent), mNfcServer(nfcServer)
+{
+ setAccessMethods(QNearFieldTarget::LlcpAccess);
+}
+
+QByteArray QNearFieldLlcpDeviceSymbian::uid() const
+{
+ return QByteArray();
+}
+
+QNearFieldTarget::Type QNearFieldLlcpDeviceSymbian::type() const
+{
+ return QNearFieldTarget::NfcForumDevice;
+}
+
+QNearFieldTarget::AccessMethods QNearFieldLlcpDeviceSymbian::accessMethods() const
+{
+ return QNearFieldTarget::LlcpAccess;
+}
+
+void QNearFieldLlcpDeviceSymbian::setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+{
+}
+
+#include "moc_qnearfieldllcpdevice_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldllcpdevice_symbian_p.h b/src/nfc/qnearfieldllcpdevice_symbian_p.h
new file mode 100644
index 00000000..e4ecb639
--- /dev/null
+++ b/src/nfc/qnearfieldllcpdevice_symbian_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QNEARFIELDLLCPDEVICE_H
+#define QNEARFIELDLLCPDEVICE_H
+
+#include <qnearfieldtarget.h>
+#include <nfcserver.h>
+
+QT_BEGIN_HEADER
+
+class QNearFieldLlcpDeviceSymbian : public QNearFieldTarget
+{
+ Q_OBJECT
+public:
+ explicit QNearFieldLlcpDeviceSymbian(RNfcServer& nfcServer, QObject *parent = 0);
+ QByteArray uid() const;
+ Type type() const;
+ AccessMethods accessMethods() const;
+ void setAccessMethods(const AccessMethods& accessMethods);
+
+ RNfcServer& nfcServer() {return mNfcServer;}
+
+private:
+ RNfcServer& mNfcServer;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDLLCPDEVICE_H
diff --git a/src/nfc/qnearfieldmanager.cpp b/src/nfc/qnearfieldmanager.cpp
new file mode 100644
index 00000000..2d9fb60e
--- /dev/null
+++ b/src/nfc/qnearfieldmanager.cpp
@@ -0,0 +1,554 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanager.h"
+#include "qnearfieldmanager_p.h"
+
+#if defined(QT_SIMULATOR)
+#include "qnearfieldmanager_simulator_p.h"
+#elif defined(Q_OS_SYMBIAN)
+#include "qnearfieldmanager_symbian_p.h"
+#elif defined(Q_WS_MAEMO_6) || defined (Q_WS_MEEGO)
+#include "qnearfieldmanager_maemo6_p.h"
+#else
+#include "qnearfieldmanagerimpl_p.h"
+#endif
+
+#include <QtCore/QMetaType>
+#include <QtCore/QMetaMethod>
+
+/*!
+ \class QNearFieldManager
+ \brief The QNearFieldManager class provides access to notifications for NFC events.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ NFC Forum devices support two modes of communications. The first mode, peer-to-peer
+ communications, is used to communicate between two NFC Forum devices. The second mode,
+ master/slave communications, is used to communicate between an NFC Forum device and an NFC
+ Forum Tag or Contactless Card. The targetDetected() signal is emitted when a target device
+ enters communications range. Communications can be initiated from the slot connected to this
+ signal.
+
+ NFC Forum devices generally operate as the master in master/slave communications. Some devices
+ are also capable of operating as the slave, so called Card Emulation mode. In this mode the
+ local NFC device emulates a NFC Forum Tag or Contactless Card and can be used to perform
+ transactions. The transaction happens entirely within a secure element on the device and only a
+ notification of the transaction is provided. The transactionDetected() signal is emitted
+ whenever a transaction occurs.
+
+ NFC Forum Tags can contain one or more messages in a standardized format. These messages are
+ encapsulated by the QNdefMessage class. Use the registerNdefMessageHandler() functions to
+ register message handlers with particular criteria. Handlers can be unregistered with the
+ unregisterNdefMessageHandler() function.
+
+ Applications can connect to the targetDetected() and targetLost() signals to get notified when
+ an NFC Forum Device or NFC Forum Tag enters or leaves proximity. Before these signals are
+ emitted target detection must be started with the startTargetDetection() function, which takes
+ a parameter to limit the type of device or tags detected. Target detection can be stopped with
+ the stopTargetDetection() function. Before a detected target can be accessed it is necessary to
+ request access rights. This must be done before the target device is touched. The
+ setTargetAccessModes() function is used to set the types of access the application wants to
+ perform on the detected target. When access is no longer required the target access modes
+ should be set to NoTargetAccess as other applications may be blocked from accessing targets.
+ The current target access modes can be retried with the targetAccessModes() function.
+
+
+ \section2 Automatically launching NDEF message handlers
+
+ It is possible to pre-register an application to receive NDEF messages matching a given
+ criteria. This is useful to get the system to automatically launch your application when a
+ matching NDEF message is received. This removes the need to have the user manually launch NDEF
+ handling applications, prior to touching a tag, or to have those applications always running
+ and using system resources.
+
+ The process of registering the handler is different on each platform. The platform specifics
+ are documented in the sections below. Qt Mobility provides a tool, \c {ndefhandlergen}, to
+ generate the platform specific registration files. The output of \c {ndefhandlergen -help} is
+ reproduced here for convenience:
+
+ \code
+ Generate platform specific NFC message handler registration files.
+ Usage: nfcxmlgen [options]
+
+ -template TEMPLATE Template to use.
+ -appname APPNAME Name of the application.
+ -apppath APPPATH Path to installed application binary.
+ -datatype DATATYPE URN of the NDEF message type to match.
+ -match MATCHSTRING Platform specific match string.
+
+ The -datatype and -match options are mutually exclusive.
+
+ Available templates: maemo6, symbian
+ \endcode
+
+ A typical invocation of the \c ndefhandlergen tool for Symbian^3 target:
+
+ \code
+ ndefhandlergen -template symbian -appname myapplication -datatype urn:nfc:ext:com.example:f
+ \endcode
+
+ and for Maemo6 target:
+
+ \code
+ ndefhandlergen -template maemo6 -appname myapplication -apppath /usr/bin/myapplication -datatype urn:nfc:ext:com.example:f
+ \endcode
+
+ Once the application has been registered as an NDEF message handler, the application only needs
+ to call the registerNdefMessageHandler() function:
+
+ \code
+ QNearFieldManager *manager = new QNearFieldManager;
+ manager->registerNdefMessageHandler(this,
+ SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget)));
+ \endcode
+
+ \section3 Symbian^3
+
+ On Symbian^3 an xml file needs to be created and installed into a particular directory on the
+ device. The format of the xml is given below.
+
+ \quotefile tools/ndefhandlergen/templates/symbian/symbian.xml
+
+ The \i {%APPNAME%} tags need to be changed to match the name of the application. The
+ \i description xml tags should be used to describe the application, however these values are
+ not used. The \i {%DATATYPE%} tag must be set with the NDEF record type to match For example
+ the following would be used to match NDEF messages that contain a RTD-URI record:
+
+ \code
+ <customproperty key="datatype">urn:nfc:wkt:U</customproperty>
+ \endcode
+
+ The following would be used to match NDEF messages that contain a custom type
+ urn:nfc:ext:example.com:f:
+
+ \code
+ <customproperty key="datatype">urn:nfc:ext:com.example:f</customproperty>
+ \endcode
+
+ The value of the \i customproperty xml tag can be set to any valid match string supported by
+ the Symbian^3 platform.
+
+ It is recommended to name the xml file after the application package name. For example
+ myapplication.xml. To install the above xml file into the correct location the following should
+ be added to the application .pro file:
+
+ \code
+ symbian {
+ ndefhandler.sources = myapplication.xml
+ ndefhandler.path = /private/2002AC7F/import/
+ DEPLOYMENT += ndefhandler
+ }
+ \endcode
+
+ \section3 Maemo6
+
+ On Maemo6 the NDEF message handler notifications are passed over D-Bus. Registration of the
+ NDEF message match criteria is done via a D-Bus call. The application must also ensure that it
+ has registered a D-Bus service name so that the application can be automatically launched when
+ a notification message is sent to the registered service.
+
+ To register the D-Bus service the two files need to be created and installed into particular
+ directories on the device. The first file is the D-Bus bus configuration file:
+
+ \quotefile tools/ndefhandlergen/templates/maemo6/maemo6.conf
+
+ The \i {%APPNAME%} tag must be replaced with the name of your application binary.
+
+ The second file is a D-Bus service file which is used by the D-Bus daemon to launch your
+ application.
+
+ \quotefile tools/ndefhandlergen/templates/maemo6/maemo6.service
+
+ The \i {%APPNAME%} tag must be replace with the name of your application binary and the
+ \i {%APPPATH%} tag must be replaced with the path to your installed application binary.
+
+ It is recommended to name these files after the application package name. For example
+ myapplication.conf and myapplication.service. To install the above files into the correct
+ location the following should be added to the application .pro file:
+
+ \code
+ maemo6 {
+ ndefhandler_conf.sources = myapplication.conf
+ ndefhandler_conf.path = /etc/dbus-1/system.d/
+
+ ndefhandler_service.sources = myapplication.service
+ ndefhandler_service.path = /usr/share/dbus-1/system-services/
+
+ DEPLOYMENT += ndefhandler_conf ndefhandler_service
+ }
+ \endcode
+
+ The NDEF message handler is registered with the following D-Bus command. Applications should
+ ensure that the following command (or similar) is executed once at installation time. For
+ example in the packages post-installation script.
+
+ \quotefile tools/ndefhandlergen/templates/maemo6/maemo6.postinst
+
+ The \i {%APPNAME%} string must be replaced with the name of the application binary. The
+ \i {%DATATYPE%} string must be replaced with the NDEF record type to match. For example the
+ following would be used to match NDEF messages that contain a RTD-URI record:
+
+ \code
+ string:"urn:nfc:wkt:U[1:*];"
+ \endcode
+
+ The following would be used to match NDEF messages that contain a custom type
+ urn:nfc:ext:example.com:f:
+
+ \code
+ string:"urn:nfc:ext:example.com:f[1:*];"
+ \endcode
+
+ Note that \c {[1:*]} indicates one or more records of the specified type must be in the NDEF
+ message. The value of the datatype string argument can be set to any valid match string
+ supported by the Maemo6 platform.
+
+ The NDEF message handler should be unregistered at uninstallation time. For example in the
+ packages pre-removal script.
+
+ \quotefile tools/ndefhandlergen/templates/maemo6/maemo6.prerm
+
+ The \i {%APPNAME%} string must be replace with the name of the application binary.
+*/
+
+/*!
+ \enum QNearFieldManager::TargetAccessMode
+
+ This enum describes the different access modes an application can have.
+
+ \value NoTargetAccess The application cannot access NFC capabilities.
+ \value NdefReadTargetAccess The application can read NDEF messages from targets by calling
+ QNearFieldTarget::readNdefMessages().
+ \value NdefWriteTargetAccess The application can write NDEF messages to targets by calling
+ QNearFieldTarget::writeNdefMessages().
+ \value TagTypeSpecificTargetAccess The application can access targets using raw commands by
+ calling QNearFieldTarget::sendCommand().
+*/
+
+/*!
+ \fn void QNearFieldManager::targetDetected(QNearFieldTarget *target)
+
+ This signal is emitted whenever a target is detected. The \a target parameter represents the
+ detected target.
+
+ This signal will be emitted for all detected targets.
+
+ QNearFieldManager maintains ownership of \a target, however, it will not be destroyed until
+ the QNearFieldManager destructor is called. Ownership may be transferred by calling
+ setParent().
+
+ Do not delete \a target from the slot connected to this signal, instead call deleteLater().
+
+ \note that if \a target is deleted before it moves out of proximity the targetLost() signal
+ will not be emitted.
+
+ \sa targetLost()
+*/
+
+/*!
+ \fn void QNearFieldManager::targetLost(QNearFieldTarget *target)
+
+ This signal is emitted whenever a target moves out of proximity. The \a target parameter
+ represents the lost target.
+
+ Do not delete \a target from the slot connected to this signal, instead use deleteLater().
+
+ \sa QNearFieldTarget::disconnected()
+*/
+
+/*!
+ \fn void QNearFieldManager::transactionDetected(const QByteArray &applicationIdentifier)
+
+ This signal is emitted when ever a transaction is performed with the application identified by
+ \a applicationIdentifier.
+
+ The \a applicationIdentifier is a byte array of up to 16 bytes as defined by ISO 7816-4 and
+ uniquely identifies the application and application vendor that was involved in the
+ transaction.
+*/
+
+/*!
+ Constructs a new near field manager with \a parent.
+*/
+QNearFieldManager::QNearFieldManager(QObject *parent)
+: QObject(parent), d_ptr(new QNearFieldManagerPrivateImpl)
+{
+ connect(d_ptr, SIGNAL(targetDetected(QNearFieldTarget*)),
+ this, SIGNAL(targetDetected(QNearFieldTarget*)));
+ connect(d_ptr, SIGNAL(targetLost(QNearFieldTarget*)),
+ this, SIGNAL(targetLost(QNearFieldTarget*)));
+}
+
+/*!
+ \internal
+
+ Constructs a new near field manager with the specified \a backend and with \a parent.
+
+ \note: This constructor is only enable for internal builds and is used for testing the
+ simulator backend.
+*/
+QNearFieldManager::QNearFieldManager(QNearFieldManagerPrivate *backend, QObject *parent)
+: QObject(parent), d_ptr(backend)
+{
+ connect(d_ptr, SIGNAL(targetDetected(QNearFieldTarget*)),
+ this, SIGNAL(targetDetected(QNearFieldTarget*)));
+ connect(d_ptr, SIGNAL(targetLost(QNearFieldTarget*)),
+ this, SIGNAL(targetLost(QNearFieldTarget*)));
+}
+
+/*!
+ Destroys the near field manager.
+*/
+QNearFieldManager::~QNearFieldManager()
+{
+ delete d_ptr;
+}
+
+/*!
+ Returns true if NFC functionality is available; otherwise returns false.
+*/
+bool QNearFieldManager::isAvailable() const
+{
+ Q_D(const QNearFieldManager);
+
+ return d->isAvailable();
+}
+
+/*!
+ Starts detecting targets of type \a targetTypes. Returns true if target detection is
+ successfully started; otherwise returns false.
+
+ Causes the targetDetected() signal to be emitted when a target with a type in \a targetTypes is
+ within proximity. If \a targetTypes is empty targets of all types will be detected.
+
+ \sa stopTargetDetection()
+*/
+bool QNearFieldManager::startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes)
+{
+ Q_D(QNearFieldManager);
+
+ if (targetTypes.isEmpty())
+ return d->startTargetDetection(QList<QNearFieldTarget::Type>() << QNearFieldTarget::AnyTarget);
+ else
+ return d->startTargetDetection(targetTypes);
+}
+
+/*!
+ \overload
+
+ Starts detecting targets of type \a targetType. Returns true if target detection is
+ successfully started; otherwise returns false. Causes the targetDetected() signal to be emitted
+ when a target with the type \a targetType is within proximity.
+*/
+bool QNearFieldManager::startTargetDetection(QNearFieldTarget::Type targetType)
+{
+ return startTargetDetection(QList<QNearFieldTarget::Type>() << targetType);
+}
+
+/*!
+ Stops detecting targets. The targetDetected() signal will no longer be emitted until another
+ call to startTargetDetection() is made.
+*/
+void QNearFieldManager::stopTargetDetection()
+{
+ Q_D(QNearFieldManager);
+
+ d->stopTargetDetection();
+}
+
+static QMetaMethod methodForSignature(QObject *object, const char *method)
+{
+ QByteArray normalizedMethod = QMetaObject::normalizedSignature(method);
+
+ if (!QMetaObject::checkConnectArgs(SIGNAL(targetDetected(QNdefMessage,QNearFieldTarget*)),
+ normalizedMethod)) {
+ qWarning("Signatures do not match: %s:%d\n", __FILE__, __LINE__);
+ return QMetaMethod();
+ }
+
+ quint8 memcode = (normalizedMethod.at(0) - '0') & 0x03;
+ normalizedMethod = normalizedMethod.mid(1);
+
+ int index;
+ switch (memcode) {
+ case QSLOT_CODE:
+ index = object->metaObject()->indexOfSlot(normalizedMethod.constData());
+ break;
+ case QSIGNAL_CODE:
+ index = object->metaObject()->indexOfSignal(normalizedMethod.constData());
+ break;
+ case QMETHOD_CODE:
+ index = object->metaObject()->indexOfMethod(normalizedMethod.constData());
+ break;
+ default:
+ index = -1;
+ }
+
+ if (index == -1)
+ return QMetaMethod();
+
+ return object->metaObject()->method(index);
+}
+
+/*!
+ Registers \a object to receive notifications on \a method when a tag has been detected and has
+ an NDEF record that matches \a typeNameFormat and \a type. The \a method on \a object should
+ have the prototype
+ 'void targetDetected(const QNdefMessage &message, QNearFieldTarget *target)'.
+
+ Returns an identifier, which can be used to unregister the handler, on success; otherwise
+ returns -1.
+
+ \note The \i target parameter of \a method may not be available on all platforms, in which case
+ \i target will be 0.
+*/
+
+int QNearFieldManager::registerNdefMessageHandler(QNdefRecord::TypeNameFormat typeNameFormat,
+ const QByteArray &type,
+ QObject *object, const char *method)
+{
+ QMetaMethod metaMethod = methodForSignature(object, method);
+ if (!metaMethod.enclosingMetaObject())
+ return -1;
+
+ QNdefFilter filter;
+ filter.appendRecord(typeNameFormat, type);
+
+ Q_D(QNearFieldManager);
+
+ return d->registerNdefMessageHandler(filter, object, metaMethod);
+}
+
+/*!
+ \fn int QNearFieldManager::registerNdefMessageHandler(QObject *object, const char *method)
+
+ Registers \a object to receive notifications on \a method when a tag has been detected and has
+ an NDEF message that matches a pre-registered message format. The \a method on \a object should
+ have the prototype
+ 'void targetDetected(const QNdefMessage &message, QNearFieldTarget *target)'.
+
+ Returns an identifier, which can be used to unregister the handler, on success; otherwise
+ returns -1.
+
+ This function is used to register a QNearFieldManager instance to receive notifications when a
+ NDEF message matching a pre-registered message format is received. See the section on
+ \l {Automatically launching NDEF message handlers}.
+
+ \note The \i target parameter of \a method may not be available on all platforms, in which case
+ \i target will be 0.
+*/
+int QNearFieldManager::registerNdefMessageHandler(QObject *object, const char *method)
+{
+ QMetaMethod metaMethod = methodForSignature(object, method);
+ if (!metaMethod.enclosingMetaObject())
+ return -1;
+
+ Q_D(QNearFieldManager);
+
+ return d->registerNdefMessageHandler(object, metaMethod);
+}
+
+/*!
+ Registers \a object to receive notifications on \a method when a tag has been detected and has
+ an NDEF message that matches \a filter is detected. The \a method on \a object should have the
+ prototype 'void targetDetected(const QNdefMessage &message, QNearFieldTarget *target)'.
+
+ Returns an identifier, which can be used to unregister the handler, on success; otherwise
+ returns -1.
+
+ \note The \i target parameter of \a method may not be available on all platforms, in which case
+ \i target will be 0.
+*/
+int QNearFieldManager::registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object, const char *method)
+{
+ QMetaMethod metaMethod = methodForSignature(object, method);
+ if (!metaMethod.enclosingMetaObject())
+ return -1;
+
+ Q_D(QNearFieldManager);
+
+ return d->registerNdefMessageHandler(filter, object, metaMethod);
+}
+
+/*!
+ Unregisters the target detect handler identified by \a handlerId.
+
+ Returns true on success; otherwise returns false.
+*/
+bool QNearFieldManager::unregisterNdefMessageHandler(int handlerId)
+{
+ Q_D(QNearFieldManager);
+
+ return d->unregisterNdefMessageHandler(handlerId);
+}
+
+/*!
+ Sets the requested target access modes to \a accessModes.
+*/
+void QNearFieldManager::setTargetAccessModes(TargetAccessModes accessModes)
+{
+ Q_D(QNearFieldManager);
+
+ TargetAccessModes removedModes = ~accessModes & d->m_requestedModes;
+ if (removedModes)
+ d->releaseAccess(removedModes);
+
+ TargetAccessModes newModes = accessModes & ~d->m_requestedModes;
+ if (newModes)
+ d->requestAccess(newModes);
+}
+
+/*!
+ Returns current requested target access modes.
+*/
+QNearFieldManager::TargetAccessModes QNearFieldManager::targetAccessModes() const
+{
+ Q_D(const QNearFieldManager);
+
+ return d->m_requestedModes;
+}
+
+#include "moc_qnearfieldmanager.cpp"
+#include "moc_qnearfieldmanager_p.cpp"
diff --git a/src/nfc/qnearfieldmanager.h b/src/nfc/qnearfieldmanager.h
new file mode 100644
index 00000000..9d3826de
--- /dev/null
+++ b/src/nfc/qnearfieldmanager.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_H
+#define QNEARFIELDMANAGER_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QObject>
+
+#include <qnearfieldtarget.h>
+#include <qndefrecord.h>
+#include <qndeffilter.h>
+
+QT_BEGIN_HEADER
+
+class QNearFieldManagerPrivate;
+class Q_CONNECTIVITY_EXPORT QNearFieldManager : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QNearFieldManager)
+
+public:
+ enum TargetAccessMode {
+ NoTargetAccess = 0x00,
+ NdefReadTargetAccess = 0x01,
+ NdefWriteTargetAccess = 0x02,
+ TagTypeSpecificTargetAccess = 0x04,
+ };
+ Q_DECLARE_FLAGS(TargetAccessModes, TargetAccessMode)
+
+ explicit QNearFieldManager(QObject *parent = 0);
+ explicit QNearFieldManager(QNearFieldManagerPrivate *backend, QObject *parent = 0);
+ ~QNearFieldManager();
+
+ bool isAvailable() const;
+
+ void setTargetAccessModes(TargetAccessModes accessModes);
+ TargetAccessModes targetAccessModes() const;
+
+ bool startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes);
+ bool startTargetDetection(QNearFieldTarget::Type targetType = QNearFieldTarget::AnyTarget);
+ void stopTargetDetection();
+
+ template<typename T>
+ int registerNdefMessageHandler(QObject *object, const char *method);
+ int registerNdefMessageHandler(QObject *object, const char *method);
+ int registerNdefMessageHandler(QNdefRecord::TypeNameFormat typeNameFormat,
+ const QByteArray &type,
+ QObject *object, const char *method);
+ int registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object, const char *method);
+
+ bool unregisterNdefMessageHandler(int handlerId);
+
+Q_SIGNALS:
+ void targetDetected(QNearFieldTarget *target);
+ void targetLost(QNearFieldTarget *target);
+ void transactionDetected(const QByteArray &applicationIdentifier);
+
+private:
+ QNearFieldManagerPrivate *d_ptr;
+};
+
+template<typename T>
+int QNearFieldManager::registerNdefMessageHandler(QObject *object, const char *method)
+{
+ T record;
+
+ return registerNdefMessageHandler(record.userTypeNameFormat(), record.type(),
+ object, method);
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QNearFieldManager::TargetAccessModes)
+
+QT_END_HEADER
+
+#endif // QNEARFIELDMANAGER_H
diff --git a/src/nfc/qnearfieldmanager_emulator.cpp b/src/nfc/qnearfieldmanager_emulator.cpp
new file mode 100644
index 00000000..0f42437c
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_emulator.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanager_emulator_p.h"
+#include "qnearfieldtarget_emulator_p.h"
+
+#include "qndefmessage.h"
+#include "qtlv_p.h"
+
+#include <QtCore/QDebug>
+
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
+{
+ TagActivator *tagActivator = TagActivator::instance();
+
+ tagActivator->initialize();
+
+ connect(tagActivator, SIGNAL(tagActivated(TagBase*)), this, SLOT(tagActivated(TagBase*)));
+ connect(tagActivator, SIGNAL(tagDeactivated(TagBase*)), this, SLOT(tagDeactivated(TagBase*)));
+}
+
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+}
+
+bool QNearFieldManagerPrivateImpl::isAvailable() const
+{
+ return true;
+}
+
+void QNearFieldManagerPrivateImpl::reset()
+{
+ TagActivator::instance()->reset();
+}
+
+void QNearFieldManagerPrivateImpl::tagActivated(TagBase *tag)
+{
+ QNearFieldTarget *target = m_targets.value(tag).data();
+ if (!target) {
+ if (dynamic_cast<NfcTagType1 *>(tag))
+ target = new TagType1(tag, this);
+ else if (dynamic_cast<NfcTagType2 *>(tag))
+ target = new TagType2(tag, this);
+ else
+ qFatal("Unknown emulator tag type");
+
+ m_targets.insert(tag, target);
+ }
+
+ targetActivated(target);
+}
+
+void QNearFieldManagerPrivateImpl::tagDeactivated(TagBase *tag)
+{
+ QNearFieldTarget *target = m_targets.value(tag).data();
+ if (!target) {
+ m_targets.remove(tag);
+ return;
+ }
+
+ targetDeactivated(target);
+}
+
+
diff --git a/src/nfc/qnearfieldmanager_emulator_p.h b/src/nfc/qnearfieldmanager_emulator_p.h
new file mode 100644
index 00000000..4d303991
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_emulator_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_EMULATOR_H
+#define QNEARFIELDMANAGER_EMULATOR_H
+
+#include "qnearfieldmanagervirtualbase_p.h"
+#include "qnearfieldtarget.h"
+#include "qndeffilter.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QWeakPointer>
+
+class TagBase;
+class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivateVirtualBase
+{
+ Q_OBJECT
+
+public:
+ QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl();
+
+ bool isAvailable() const;
+
+ void reset();
+
+private slots:
+ void tagActivated(TagBase *tag);
+ void tagDeactivated(TagBase *tag);
+
+private:
+ void ndefReceived(const QNdefMessage &message, QNearFieldTarget *target);
+
+ QMap<TagBase *, QWeakPointer<QNearFieldTarget> > m_targets;
+
+};
+
+#endif // QNEARFIELDMANAGER_EMULATOR_H
diff --git a/src/nfc/qnearfieldmanager_maemo6.cpp b/src/nfc/qnearfieldmanager_maemo6.cpp
new file mode 100644
index 00000000..a8c21bac
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_maemo6.cpp
@@ -0,0 +1,449 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanager_maemo6_p.h"
+#include "qnearfieldtarget_maemo6_p.h"
+#include "manager_interface.h"
+#include "maemo6/adapter_interface_p.h"
+#include "maemo6/target_interface_p.h"
+#include "maemo6/tag_interface_p.h"
+#include "ndefhandler_adaptor.h"
+#include "accessrequestor_adaptor.h"
+
+#include <qnearfieldtagtype1.h>
+
+#include <QtDBus/QDBusConnection>
+
+using namespace com::nokia::nfc;
+
+static QAtomicInt handlerId = 0;
+static const char * const registeredHandlerPath = "/com/nokia/nfc/ndefhandler";
+static const char * const accessRequesterPath = "/com/nokia/nfc/accessRequester/";
+static const char * const connectionUuid = "46a15ee4-b5ce-4395-9d76-c440cc3838c6";
+
+static inline bool matchesTarget(QNearFieldTarget::Type type,
+ const QList<QNearFieldTarget::Type> &types)
+{
+ return types.contains(type) || types.contains(QNearFieldTarget::AnyTarget);
+}
+
+NdefHandler::NdefHandler(QNearFieldManagerPrivateImpl *manager, const QString &serviceName,
+ const QString &path, QObject *object, const QMetaMethod &method)
+: m_manager(manager), m_adaptor(0), m_object(object), m_method(method),
+ m_serviceName(serviceName), m_path(path)
+{
+ QDBusConnection handlerConnection =
+ QDBusConnection::connectToBus(QDBusConnection::SystemBus, connectionUuid);
+ if (serviceName != handlerConnection.baseService()) {
+ handlerConnection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, serviceName);
+
+ if (!handlerConnection.registerService(serviceName))
+ return;
+ }
+
+ m_adaptor = new NDEFHandlerAdaptor(this);
+
+ if (!handlerConnection.registerObject(path, this)) {
+ delete m_adaptor;
+ m_adaptor = 0;
+ }
+}
+
+NdefHandler::~NdefHandler()
+{
+ delete m_adaptor;
+}
+
+bool NdefHandler::isValid() const
+{
+ return m_adaptor;
+}
+
+QString NdefHandler::serviceName() const
+{
+ return m_serviceName;
+}
+
+QString NdefHandler::path() const
+{
+ return m_path;
+}
+
+void NdefHandler::NDEFData(const QDBusObjectPath &target, const QByteArray &message)
+{
+ m_method.invoke(m_object, Q_ARG(QNdefMessage, QNdefMessage::fromByteArray(message)),
+ Q_ARG(QNearFieldTarget *, m_manager->targetForPath(target.path())));
+}
+
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
+: m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus,
+ QLatin1String(connectionUuid))),
+ m_accessAgent(0)
+{
+ qDBusRegisterMetaType<QList<QByteArray> >();
+
+ m_manager = new Manager(QLatin1String("com.nokia.nfc"), QLatin1String("/"), m_connection);
+
+ QDBusObjectPath defaultAdapterPath = m_manager->DefaultAdapter();
+
+ m_adapter = new Adapter(QLatin1String("com.nokia.nfc"), defaultAdapterPath.path(),
+ m_connection);
+
+ if (!m_adapter->isValid())
+ return;
+}
+
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+ foreach (int id, m_registeredHandlers.keys())
+ unregisterNdefMessageHandler(id);
+
+ delete m_manager;
+ delete m_adapter;
+}
+
+bool QNearFieldManagerPrivateImpl::isAvailable() const
+{
+ return m_manager->isValid();
+}
+
+bool QNearFieldManagerPrivateImpl::startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes)
+{
+ m_detectTargetTypes = targetTypes;
+
+ connect(m_adapter, SIGNAL(TargetDetected(QDBusObjectPath)),
+ this, SLOT(_q_targetDetected(QDBusObjectPath)));
+ connect(m_adapter, SIGNAL(TargetLost(QDBusObjectPath)),
+ this, SLOT(_q_targetLost(QDBusObjectPath)));
+
+ return true;
+}
+
+void QNearFieldManagerPrivateImpl::stopTargetDetection()
+{
+ m_detectTargetTypes.clear();
+
+ disconnect(m_adapter, SIGNAL(TargetDetected(QDBusObjectPath)),
+ this, SLOT(_q_targetDetected(QDBusObjectPath)));
+ disconnect(m_adapter, SIGNAL(TargetLost(QDBusObjectPath)),
+ this, SLOT(_q_targetLost(QDBusObjectPath)));
+}
+
+QNearFieldTarget *QNearFieldManagerPrivateImpl::targetForPath(const QString &path)
+{
+ QNearFieldTarget *nearFieldTarget = m_targets.value(path).data();
+
+ if (!nearFieldTarget) {
+ Target *target = new Target(QLatin1String("com.nokia.nfc"), path, m_connection);
+
+ const QString type = target->type();
+
+ if (type == QLatin1String("tag")) {
+ Tag *tag = new Tag(QLatin1String("com.nokia.nfc"), path, m_connection);
+
+ const QString tagTechnology = tag->technology();
+ if (tagTechnology == QLatin1String("jewel"))
+ nearFieldTarget = new TagType1(this, target, tag);
+ else if (tagTechnology == QLatin1String("mifare-ul"))
+ nearFieldTarget = new TagType2(this, target, tag);
+ else if (tagTechnology == QLatin1String("felica"))
+ nearFieldTarget = new TagType3(this, target, tag);
+ else if (tagTechnology == QLatin1String("iso-4a"))
+ nearFieldTarget = new TagType4(this, target, tag);
+ else
+ nearFieldTarget = new NearFieldTarget<QNearFieldTarget>(this, target, tag);
+ } else if (type == QLatin1String("device")) {
+ Device *device = new Device(QLatin1String("com.nokia.nfc"), path, m_connection);
+ nearFieldTarget = new NearFieldTarget<QNearFieldTarget>(this, target, device);
+ }
+
+ if (nearFieldTarget)
+ m_targets.insert(path, nearFieldTarget);
+ }
+
+ return nearFieldTarget;
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(const QString &filter,
+ QObject *object,
+ const QMetaMethod &method)
+{
+ int id = handlerId.fetchAndAddOrdered(1);
+ const QString handlerPath =
+ QLatin1String(registeredHandlerPath) + QLatin1Char('/') + QString::number(id);
+
+ NdefHandler *handler = new NdefHandler(this, m_connection.baseService(),
+ handlerPath, object, method);
+ if (!handler->isValid()) {
+ delete handler;
+ return -1;
+ }
+
+ QDBusPendingReply<> reply =
+ m_manager->RegisterNDEFHandler(QLatin1String("system"),
+ m_connection.baseService(),
+ QDBusObjectPath(handlerPath),
+ QLatin1String("any"),
+ filter,
+ QCoreApplication::applicationName());
+
+ if (reply.isError()) {
+ delete handler;
+ return -1;
+ }
+
+ m_registeredHandlers[id] = handler;
+
+ return id;
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(QObject *object,
+ const QMetaMethod &method)
+{
+ QFileInfo fi(qApp->applicationFilePath());
+ const QString serviceName = QLatin1String("com.nokia.qt.nfc.") + fi.baseName();
+
+ int id = handlerId.fetchAndAddOrdered(1);
+
+ const QString handlerPath = QLatin1String(registeredHandlerPath);
+
+ NdefHandler *handler = new NdefHandler(this, serviceName, handlerPath, object, method);
+ if (!handler->isValid()) {
+ delete handler;
+ return -1;
+ }
+
+ m_registeredHandlers[id] = handler;
+
+ return id;
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object,
+ const QMetaMethod &method)
+{
+ QString matchString;
+
+ if (filter.orderMatch())
+ matchString += QLatin1String("sequence:");
+ else
+ matchString += QLatin1String("unordered:");
+
+ for (int i = 0; i < filter.recordCount(); ++i) {
+ QNdefFilter::Record record = filter.recordAt(i);
+
+ QString type;
+
+ switch (record.typeNameFormat) {
+ case QNdefRecord::NfcRtd:
+ type = QLatin1String("urn:nfc:wkt:") + record.type;
+ break;
+ case QNdefRecord::ExternalRtd:
+ type = QLatin1String("urn:nfc:ext:") + record.type;
+ break;
+ case QNdefRecord::Mime:
+ type = record.type;
+ break;
+ default:
+ qWarning("Unsupported filter type");
+ return -1;
+ }
+
+ matchString += QLatin1Char('\'') + type + QLatin1Char('\'');
+ matchString += QLatin1Char('[');
+
+ if (record.minimum == UINT_MAX)
+ matchString += QLatin1Char('*');
+ else
+ matchString += QString::number(record.minimum);
+
+ matchString += QLatin1Char(':');
+
+ if (record.maximum == UINT_MAX)
+ matchString += QLatin1Char('*');
+ else
+ matchString += QString::number(record.maximum);
+
+ matchString += QLatin1Char(']');
+
+ if (i == filter.recordCount() - 1)
+ matchString += QLatin1Char(';');
+ else
+ matchString += QLatin1Char(',');
+ }
+
+ return registerNdefMessageHandler(matchString, object, method);
+}
+
+bool QNearFieldManagerPrivateImpl::unregisterNdefMessageHandler(int id)
+{
+ if (id < 0)
+ return false;
+
+ NdefHandler *handler = m_registeredHandlers.take(id);
+
+ QDBusPendingReply<> reply = m_manager->UnregisterNDEFHandler(QLatin1String("system"),
+ handler->serviceName(),
+ QDBusObjectPath(handler->path()));
+
+ delete handler;
+
+ return true;
+}
+
+static QStringList accessModesToKind(QNearFieldManager::TargetAccessModes accessModes)
+{
+ QStringList kind;
+
+ if (accessModes & QNearFieldManager::NdefReadTargetAccess)
+ kind.append(QLatin1String("tag.ndef.read"));
+
+ if (accessModes & QNearFieldManager::NdefWriteTargetAccess)
+ kind.append(QLatin1String("tag.ndef.write"));
+
+ if (accessModes & QNearFieldManager::TagTypeSpecificTargetAccess)
+ kind.append(QLatin1String("tag.raw"));
+
+ return kind;
+}
+
+void QNearFieldManagerPrivateImpl::requestAccess(QNearFieldManager::TargetAccessModes accessModes)
+{
+ const QString requesterPath =
+ QLatin1String(accessRequesterPath) + QString::number(quintptr(this));
+
+ if (!m_accessAgent) {
+ m_accessAgent = new AccessRequestorAdaptor(this);
+ if (!m_connection.registerObject(requesterPath, this)) {
+ delete m_accessAgent;
+ m_accessAgent = 0;
+ return;
+ }
+ }
+
+ foreach (const QString &kind, accessModesToKind(accessModes))
+ m_adapter->RequestAccess(QDBusObjectPath(requesterPath), kind);
+
+ QNearFieldManagerPrivate::requestAccess(accessModes);
+}
+
+void QNearFieldManagerPrivateImpl::releaseAccess(QNearFieldManager::TargetAccessModes accessModes)
+{
+ const QString requesterPath =
+ QLatin1String(accessRequesterPath) + QString::number(quintptr(this));
+
+ foreach (const QString &kind, accessModesToKind(accessModes))
+ m_adapter->CancelAccessRequest(QDBusObjectPath(requesterPath), kind);
+
+ QNearFieldManagerPrivate::releaseAccess(accessModes);
+}
+
+void QNearFieldManagerPrivateImpl::AccessFailed(const QDBusObjectPath &target, const QString &kind,
+ const QString &error)
+{
+ qDebug() << "Access for" << target.path() << kind << "failed with error:" << error;
+}
+
+void QNearFieldManagerPrivateImpl::AccessGranted(const QDBusObjectPath &target,
+ const QString &kind)
+{
+ Q_UNUSED(kind);
+
+ if (m_pendingDetectedTargets.contains(target.path())) {
+ m_pendingDetectedTargets[target.path()].stop();
+ m_pendingDetectedTargets.remove(target.path());
+ }
+
+ emitTargetDetected(target.path());
+}
+
+void QNearFieldManagerPrivateImpl::timerEvent(QTimerEvent *event)
+{
+ QMutableMapIterator<QString, QBasicTimer> i(m_pendingDetectedTargets);
+ while (i.hasNext()) {
+ i.next();
+
+ if (i.value().timerId() == event->timerId()) {
+ i.value().stop();
+
+ const QString target = i.key();
+
+ i.remove();
+
+ emitTargetDetected(target);
+
+ break;
+ }
+ }
+}
+
+void QNearFieldManagerPrivateImpl::emitTargetDetected(const QString &targetPath)
+{
+ QNearFieldTarget *target = targetForPath(targetPath);
+ if (target && matchesTarget(target->type(), m_detectTargetTypes))
+ emit targetDetected(target);
+}
+
+void QNearFieldManagerPrivateImpl::_q_targetDetected(const QDBusObjectPath &targetPath)
+{
+ if (!m_requestedModes)
+ emitTargetDetected(targetPath.path());
+ else
+ m_pendingDetectedTargets[targetPath.path()].start(500, this);
+}
+
+void QNearFieldManagerPrivateImpl::_q_targetLost(const QDBusObjectPath &targetPath)
+{
+ QNearFieldTarget *nearFieldTarget = m_targets.value(targetPath.path()).data();
+
+ // haven't seen target so just drop this event
+ if (!nearFieldTarget) {
+ // We either haven't seen target (started after target was detected by system) or the
+ // application deleted the target. Remove from map and don't emit anything.
+ m_targets.remove(targetPath.path());
+ return;
+ }
+
+ if (matchesTarget(nearFieldTarget->type(), m_detectTargetTypes))
+ emit targetLost(nearFieldTarget);
+}
+
+#include "moc_qnearfieldmanager_maemo6_p.cpp"
diff --git a/src/nfc/qnearfieldmanager_maemo6_p.h b/src/nfc/qnearfieldmanager_maemo6_p.h
new file mode 100644
index 00000000..f342398a
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_maemo6_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_MAEMO6_P_H
+#define QNEARFIELDMANAGER_MAEMO6_P_H
+
+#include "qnearfieldmanager_p.h"
+#include "qnearfieldmanager.h"
+#include "qnearfieldtarget.h"
+
+#include <QtCore/QWeakPointer>
+#include <QtCore/QMap>
+#include <QtCore/QPair>
+#include <QtCore/QMetaMethod>
+#include <QtCore/QBasicTimer>
+
+#include <QtDBus/QDBusConnection>
+
+QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
+
+class ComNokiaNfcManagerInterface;
+class ComNokiaNfcAdapterInterface;
+class NDEFHandlerAdaptor;
+class AccessRequestorAdaptor;
+
+class QNearFieldManagerPrivateImpl;
+
+class NdefHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ NdefHandler(QNearFieldManagerPrivateImpl *manager, const QString &serviceName,
+ const QString &path, QObject *object, const QMetaMethod &method);
+ ~NdefHandler();
+
+ bool isValid() const;
+
+ QString serviceName() const;
+ QString path() const;
+
+private:
+ Q_INVOKABLE void NDEFData(const QDBusObjectPath &target, const QByteArray &message);
+
+ QNearFieldManagerPrivateImpl *m_manager;
+ NDEFHandlerAdaptor *m_adaptor;
+ QObject *m_object;
+ QMetaMethod m_method;
+ QString m_serviceName;
+ QString m_path;
+};
+
+class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivate
+{
+ Q_OBJECT
+
+public:
+ QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl();
+
+ bool isAvailable() const;
+
+ bool startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes);
+ void stopTargetDetection();
+
+ QNearFieldTarget *targetForPath(const QString &path);
+
+ int registerNdefMessageHandler(const QString &filter,
+ QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object, const QMetaMethod &method);
+ bool unregisterNdefMessageHandler(int handlerId);
+
+ void requestAccess(QNearFieldManager::TargetAccessModes accessModes);
+ void releaseAccess(QNearFieldManager::TargetAccessModes accessModes);
+
+ // Access Agent Adaptor
+ Q_INVOKABLE void AccessFailed(const QDBusObjectPath &target, const QString &kind,
+ const QString &error);
+ Q_INVOKABLE void AccessGranted(const QDBusObjectPath &target, const QString &kind);
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private slots:
+ void emitTargetDetected(const QString &targetPath);
+ void _q_targetDetected(const QDBusObjectPath &targetPath);
+ void _q_targetLost(const QDBusObjectPath &targetPath);
+
+private:
+ QDBusConnection m_connection;
+ ComNokiaNfcManagerInterface *m_manager;
+ ComNokiaNfcAdapterInterface *m_adapter;
+
+ QList<QNearFieldTarget::Type> m_detectTargetTypes;
+ QMap<QString, QWeakPointer<QNearFieldTarget> > m_targets;
+
+ AccessRequestorAdaptor *m_accessAgent;
+
+ QMap<int, NdefHandler *> m_registeredHandlers;
+
+ QMap<QString, QBasicTimer> m_pendingDetectedTargets;
+};
+
+#endif // QNEARFIELDMANAGER_MAEMO6_P_H
diff --git a/src/nfc/qnearfieldmanager_p.h b/src/nfc/qnearfieldmanager_p.h
new file mode 100644
index 00000000..648a1978
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_P_H
+#define QNEARFIELDMANAGER_P_H
+
+#include "qnearfieldmanager.h"
+#include "qnearfieldtarget.h"
+#include "qndefrecord.h"
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+class QNdefFilter;
+
+class QM_AUTOTEST_EXPORT QNearFieldManagerPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QNearFieldManagerPrivate(QObject *parent = 0)
+ : QObject(parent)
+ {
+ }
+
+ ~QNearFieldManagerPrivate()
+ {
+ }
+
+ virtual bool isAvailable() const
+ {
+ return false;
+ }
+
+ virtual bool startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes)
+ {
+ Q_UNUSED(targetTypes);
+
+ return false;
+ }
+
+ virtual void stopTargetDetection()
+ {
+ }
+
+ virtual int registerNdefMessageHandler(QObject *object, const QMetaMethod &/*method*/)
+ {
+ Q_UNUSED(object);
+
+ return -1;
+ }
+
+ virtual int registerNdefMessageHandler(const QNdefFilter &/*filter*/,
+ QObject *object, const QMetaMethod &/*method*/)
+ {
+ Q_UNUSED(object);
+
+ return -1;
+ }
+
+ virtual bool unregisterNdefMessageHandler(int handlerId)
+ {
+ Q_UNUSED(handlerId);
+
+ return false;
+ }
+
+ virtual void requestAccess(QNearFieldManager::TargetAccessModes accessModes)
+ {
+ m_requestedModes |= accessModes;
+ }
+
+ virtual void releaseAccess(QNearFieldManager::TargetAccessModes accessModes)
+ {
+ m_requestedModes &= ~accessModes;
+ }
+
+signals:
+ void targetDetected(QNearFieldTarget *target);
+ void targetLost(QNearFieldTarget *target);
+
+public:
+ QNearFieldManager::TargetAccessModes m_requestedModes;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDMANAGER_P_H
diff --git a/src/nfc/qnearfieldmanager_simulator.cpp b/src/nfc/qnearfieldmanager_simulator.cpp
new file mode 100644
index 00000000..1d7f5318
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_simulator.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanager_simulator_p.h"
+#include "qnearfieldmanager.h"
+#include "qnearfieldtarget_p.h"
+#include "qnearfieldtagtype1.h"
+#include "qndefmessage.h"
+
+#include <mobilityconnection_p.h>
+#include <QtGui/private/qsimulatordata_p.h>
+
+#include <QtCore/QCoreApplication>
+
+using namespace QtSimulatorPrivate;
+
+namespace Simulator {
+
+class TagType1 : public QNearFieldTagType1
+{
+public:
+ TagType1(const QByteArray &uid, QObject *parent);
+ ~TagType1();
+
+ QByteArray uid() const;
+
+ AccessMethods accessMethods() const;
+
+ RequestId sendCommand(const QByteArray &command);
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+private:
+ QByteArray m_uid;
+};
+
+TagType1::TagType1(const QByteArray &uid, QObject *parent)
+: QNearFieldTagType1(parent), m_uid(uid)
+{
+}
+
+TagType1::~TagType1()
+{
+}
+
+QByteArray TagType1::uid() const
+{
+ return m_uid;
+}
+
+QNearFieldTarget::AccessMethods TagType1::accessMethods() const
+{
+ return NdefAccess | TagTypeSpecificAccess;
+}
+
+QNearFieldTarget::RequestId TagType1::sendCommand(const QByteArray &command)
+{
+ quint16 crc = qNfcChecksum(command.constData(), command.length());
+
+ RequestId id(new RequestIdPrivate);
+
+ MobilityConnection *connection = MobilityConnection::instance();
+ QByteArray response =
+ RemoteMetacall<QByteArray>::call(connection->sendSocket(), WaitSync, "nfcSendCommand",
+ command + char(crc & 0xff) + char(crc >> 8));
+
+ if (response.isEmpty()) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, NoResponseError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ // check crc
+ if (qNfcChecksum(response.constData(), response.length()) != 0) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, ChecksumMismatchError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ response.chop(2);
+
+ QMetaObject::invokeMethod(this, "handleResponse", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::RequestId, id), Q_ARG(QByteArray, response));
+
+ return id;
+}
+
+bool TagType1::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ QCoreApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+ return QNearFieldTagType1::waitForRequestCompleted(id, msecs);
+}
+
+class NfcConnection : public QObject
+{
+ Q_OBJECT
+
+public:
+ NfcConnection();
+ virtual ~NfcConnection();
+
+signals:
+ void targetEnteringProximity(const QByteArray &uid);
+ void targetLeavingProximity(const QByteArray &uid);
+};
+
+NfcConnection::NfcConnection()
+: QObject(MobilityConnection::instance())
+{
+ MobilityConnection *connection = MobilityConnection::instance();
+ connection->addMessageHandler(this);
+
+ RemoteMetacall<void>::call(connection->sendSocket(), NoSync, "setRequestsNfc");
+}
+
+NfcConnection::~NfcConnection()
+{
+}
+
+}
+
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
+: nfcConnection(new Simulator::NfcConnection)
+{
+ connect(nfcConnection, SIGNAL(targetEnteringProximity(QByteArray)),
+ this, SLOT(targetEnteringProximity(QByteArray)));
+ connect(nfcConnection, SIGNAL(targetLeavingProximity(QByteArray)),
+ this, SLOT(targetLeavingProximity(QByteArray)));
+}
+
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+ delete nfcConnection;
+}
+
+bool QNearFieldManagerPrivateImpl::isAvailable() const
+{
+ return true;
+}
+
+void QNearFieldManagerPrivateImpl::targetEnteringProximity(const QByteArray &uid)
+{
+ QNearFieldTarget *target = m_targets.value(uid).data();
+ if (!target) {
+ target = new Simulator::TagType1(uid, this);
+ m_targets.insert(uid, target);
+ }
+
+ targetActivated(target);
+}
+
+void QNearFieldManagerPrivateImpl::targetLeavingProximity(const QByteArray &uid)
+{
+ QNearFieldTarget *target = m_targets.value(uid).data();
+ if (!target) {
+ m_targets.remove(uid);
+ return;
+ }
+
+ targetDeactivated(target);
+}
+
+#include "qnearfieldmanager_simulator.moc"
+#include "moc_qnearfieldmanager_simulator_p.cpp"
diff --git a/src/nfc/qnearfieldmanager_simulator_p.h b/src/nfc/qnearfieldmanager_simulator_p.h
new file mode 100644
index 00000000..a55f3e94
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_simulator_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_SIMULATOR_P_H
+#define QNEARFIELDMANAGER_SIMULATOR_P_H
+
+#include "qnearfieldmanagervirtualbase_p.h"
+
+#include <QtCore/QWeakPointer>
+
+QT_BEGIN_HEADER
+
+namespace Simulator {
+class NfcConnection;
+}
+
+class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivateVirtualBase
+{
+ Q_OBJECT
+
+public:
+ QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl();
+
+ bool isAvailable() const;
+
+private slots:
+ void targetEnteringProximity(const QByteArray &uid);
+ void targetLeavingProximity(const QByteArray &uid);
+
+private:
+ Simulator::NfcConnection *nfcConnection;
+ QMap<QByteArray, QWeakPointer<QNearFieldTarget> > m_targets;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDMANAGER_SIMULATOR_P_H
diff --git a/src/nfc/qnearfieldmanager_symbian.cpp b/src/nfc/qnearfieldmanager_symbian.cpp
new file mode 100644
index 00000000..8492d526
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_symbian.cpp
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qservicefilter.h>
+#include <qservicemanager.h>
+#include <QCoreApplication>
+#include <ndefmessage.h>
+
+#include "qnearfieldmanager_symbian_p.h"
+#include "qndefmessage.h"
+#include "symbian/nearfieldmanager_symbian.h"
+#include "symbian/debug.h"
+#include "symbian/nearfieldutility_symbian.h"
+
+Proxy contentHandlerProxy;
+
+Proxy::Proxy(QObject* parent) : QObject (parent)
+{
+}
+
+ContentHandlerInterface::ContentHandlerInterface(QObject* parent)
+ : QObject(parent)
+{
+}
+void ContentHandlerInterface::handleMessage(const QByteArray& btArray)
+{
+ // incoming message from ECOM content handler loader eventually cause object & method registered via below
+ // registerNdefMessageHandler to be invoked with message as parameter. i.e. MyContentHandler::handleMessage(message)
+ // from above.
+
+
+ QNdefMessage msg = QNdefMessage::fromByteArray(btArray);
+ QMetaObject::invokeMethod(&contentHandlerProxy, "handleMessage", Q_ARG(QNdefMessage, msg));
+
+
+}
+/*
+ \class QNearFieldManagerPrivateImpl
+ \brief The QNearFieldManagerPrivateImpl class provides symbian backend access to NFC service.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+
+ A Qt-Symbian wrapper implementation class to support symbian NFC backend.
+*/
+
+/*
+ Constructs a new near field manager private implementation.
+*/
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl(): m_symbianbackend(NULL),m_target(NULL),m_serviceRegister(NULL)
+{
+ BEGIN
+ TRAPD(err, m_symbianbackend = CNearFieldManager::NewL(*this));
+ END
+}
+
+/*
+ Destroys the near field manager private implementation.
+*/
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+ BEGIN
+ delete m_target;
+ qDeleteAll(m_targetList);
+ delete m_serviceRegister;
+ delete m_symbianbackend;
+ END
+}
+
+bool QNearFieldManagerPrivateImpl::isAvailable() const
+{
+ return m_symbianbackend;
+}
+
+/*
+ Helper function to get the free handler id.
+*/
+int QNearFieldManagerPrivateImpl::getFreeId()
+{
+ BEGIN
+ if (!m_freeIds.isEmpty())
+ return m_freeIds.takeFirst();
+
+ m_registeredHandlers.append(Callback());
+ END
+ return m_registeredHandlers.count() - 1;
+}
+
+/*
+ Registers \a object to receive notifications on \a method when a tag with a tag type of
+ \a targetType has been detected and has an NDEF message is detected. The
+ \a method on \a object should have the prototype
+ 'void targetDetected(const QNdefMessage &message, QNearFieldTarget *target)'.
+
+ Returns an identifier, which can be used to unregister the handler, on success; otherwise
+ returns -1.
+*/
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(QObject *object,
+ const QMetaMethod &method)
+{
+ QServiceFilter filter("com.nokia.qt.nfc.NdefMessageHandler");
+ QCoreApplication* app = QCoreApplication::instance();
+ //The appfile path will return something like \sys\bin\nfcspserviceprovider.exe
+ //but we only need nfcspserviceprovider as service name
+ QString appfilepath = app->applicationFilePath();
+ TInt lastseprator = appfilepath.lastIndexOf("\\");
+ TInt lastdot = appfilepath.lastIndexOf(".");
+ QString servicename = appfilepath.mid(lastseprator+1, lastdot-lastseprator-1);
+ qDebug() << "application name: " << servicename << endl;
+
+ filter.setServiceName(servicename);
+ QServiceManager sfManager;
+
+ if (!sfManager.findInterfaces(filter).isEmpty())
+ {
+ // This application has been registered as a content handler (via the xml at install time), start the service
+ m_chobject = object;
+ m_chmethod = method;
+
+ connect(&contentHandlerProxy, SIGNAL(handleMessage(QNdefMessage)),
+ this, SLOT(_q_privateHandleMessageSlot(QNdefMessage)));
+ if ( !m_serviceRegister )
+ {
+ m_serviceRegister = new QRemoteServiceRegister();
+ QRemoteServiceRegister::Entry entry =
+ m_serviceRegister->createEntry<ContentHandlerInterface>(servicename,
+ "com.nokia.qt.nfc.NdefMessageHandler",
+ "1.0");
+ entry.setInstantiationType(QRemoteServiceRegister::PrivateInstance);
+ m_serviceRegister->publishEntries(servicename);
+ }
+ return 0xffff;
+
+ } else {
+ // not supported if not registered as a content handler using this API
+ return -1;
+ }
+}
+
+/*
+ Registers \a object to receive notifications on \a method when a tag with a tag type of
+ \a targetType has been detected and has an NDEF message that matches \a filter is detected. The
+ \a method on \a object should have the prototype
+ 'void targetDetected(const QNdefMessage &message, QNearFieldTarget *target)'.
+
+ Returns an identifier, which can be used to unregister the handler, on success; otherwise
+ returns -1.
+*/
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object,
+ const QMetaMethod &method)
+{
+ if (!m_symbianbackend)
+ return -1;
+
+ BEGIN
+ int id = getFreeId();
+
+ Callback &callback = m_registeredHandlers[id];
+
+ callback.filter = filter;
+ callback.object = object;
+ callback.method = method;
+
+ for( int i = 0; i < filter.recordCount(); ++i)
+ {
+ QNdefRecord::TypeNameFormat tnf = filter.recordAt(i).typeNameFormat;
+ QByteArray type = filter.recordAt(i).type;
+ if (m_symbianbackend->AddNdefSubscription( tnf, type ) < 0)
+ {
+ for (int j = 0; j < i; ++j)//rollback the previous subscriptions
+ {
+ QNdefRecord::TypeNameFormat n = filter.recordAt(j).typeNameFormat;
+ QByteArray t = filter.recordAt(j).type;
+ m_symbianbackend->RemoveNdefSubscription( n, t );
+ }
+ m_freeIds.append(id);//push back the id to freeid list
+ END
+ return -1;
+ }
+ }
+ END
+ return id;
+}
+
+/*
+ Unregisters the target detect handler identified by \a id.
+
+ Returns true on success; otherwise returns false.
+*/
+bool QNearFieldManagerPrivateImpl::unregisterNdefMessageHandler(int id)
+{
+ if (!m_symbianbackend)
+ return false;
+
+ BEGIN
+ if ( 0xffff == id )
+ {
+ disconnect(&contentHandlerProxy, SIGNAL(handleMessage(QNdefMessage)),
+ this, SLOT(_q_privateHandleMessageSlot(QNdefMessage)));
+ return true;
+ }
+ if (id < 0 || id >= m_registeredHandlers.count() || m_freeIds.contains(id))
+ return false;
+
+ m_freeIds.append(id);
+
+ for ( int i = 0; i < m_registeredHandlers[id].filter.recordCount(); ++i)
+ {
+ QNdefRecord::TypeNameFormat tnf = m_registeredHandlers[id].filter.recordAt(i).typeNameFormat;
+ QByteArray type = m_registeredHandlers[id].filter.recordAt(i).type;
+ m_symbianbackend->RemoveNdefSubscription( tnf, type );
+ }
+
+ while (m_freeIds.contains(m_registeredHandlers.count() - 1)) {
+ m_freeIds.removeAll(m_registeredHandlers.count() - 1);
+ m_registeredHandlers.removeLast();
+ }
+ END
+ return true;
+}
+
+bool QNearFieldManagerPrivateImpl::startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes)
+{
+ if (!m_symbianbackend)
+ return false;
+
+ BEGIN
+ TRAPD(err, m_symbianbackend->StartTargetDetectionL(targetTypes));
+ END
+ return err == KErrNone;
+}
+
+void QNearFieldManagerPrivateImpl::stopTargetDetection()
+{
+ BEGIN
+ if (m_symbianbackend)
+ m_symbianbackend->stopTargetDetection();
+ END
+}
+
+struct VerifyRecord
+{
+ QNdefFilter::Record filterRecord;
+ unsigned int count;
+};
+
+/*
+ Callback function when symbian NFC backend found the NFC \a target.
+*/
+void QNearFieldManagerPrivateImpl::targetFound(QNearFieldTarget *target)
+{
+ BEGIN
+ if (!target){
+ return;
+ }
+ if (m_target){
+ m_targetList.append(m_target);
+ }
+ m_target = target;
+ emit targetDetected(target);
+ END
+}
+
+/*
+ * Private slot to be invoked by QT content handler loader
+ */
+void QNearFieldManagerPrivateImpl::_q_privateHandleMessageSlot(QNdefMessage aMsg)
+ {
+
+ m_chmethod.invoke(m_chobject, Q_ARG(QNdefMessage, aMsg), Q_ARG(QNearFieldTarget* , NULL));
+ }
+
+/*
+ Helper function to invoke the filtered TargetDetectedHandler for a found \a target.
+*/
+
+void QNearFieldManagerPrivateImpl::invokeNdefMessageHandler(const QNdefMessage msg)
+{
+ BEGIN
+ for (int i = 0; i < m_registeredHandlers.count(); ++i) {
+ if (m_freeIds.contains(i))
+ continue;
+ Callback &callback = m_registeredHandlers[i];
+ bool matched = true;
+ QList<VerifyRecord> filterRecords;
+ for (int j = 0; j < callback.filter.recordCount(); ++j) {
+ VerifyRecord vr;
+ vr.count = 0;
+ vr.filterRecord = callback.filter.recordAt(j);
+ filterRecords.append(vr);
+ }
+
+ foreach (const QNdefRecord &record, msg) {
+ for (int j = 0; matched && (j < filterRecords.count()); ++j) {
+ VerifyRecord &vr = filterRecords[j];
+
+ if (vr.filterRecord.typeNameFormat == record.typeNameFormat() &&
+ vr.filterRecord.type == record.type()) {
+ ++vr.count;
+ break;
+ } else {
+ if (callback.filter.orderMatch()) {
+ if (vr.filterRecord.minimum <= vr.count &&
+ vr.count <= vr.filterRecord.maximum) {
+ continue;
+ } else {
+ matched = false;
+ }
+ }
+ }
+ }
+ }//end of foreach (const QNdefRecord &record, msg) {
+
+ for (int j = 0; matched && (j < filterRecords.count()); ++j) {
+ const VerifyRecord &vr = filterRecords.at(j);
+
+ if (vr.filterRecord.minimum <= vr.count && vr.count <= vr.filterRecord.maximum)
+ continue;
+ else
+ matched = false;
+ }
+
+ if (matched) {
+ callback.method.invoke(callback.object, Q_ARG(QNdefMessage, msg),
+ Q_ARG(QNearFieldTarget *, NULL));
+ }
+
+ }
+ END
+}
+
+/*
+ Callback function when symbian NFC backend lost the NFC \a target.
+*/
+void QNearFieldManagerPrivateImpl::targetDisconnected()
+{
+ BEGIN
+ if (m_target)
+ {
+ QMetaObject::invokeMethod(m_target, "disconnected");
+ emit targetLost(m_target);
+ }
+ END
+}
+
+#include "moc_qnearfieldmanager_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldmanager_symbian_p.h b/src/nfc/qnearfieldmanager_symbian_p.h
new file mode 100644
index 00000000..d1df3397
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_symbian_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_SYMBIAN_P_H_
+#define QNEARFIELDMANAGER_SYMBIAN_P_H_
+
+
+#include "qnearfieldmanager_p.h"
+#include "qnearfieldtarget.h"
+#include "qndeffilter.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QMetaMethod>
+#include <QPointer>
+#include <QList>
+#include <qremoteserviceregister.h>
+
+class CNearFieldManager;
+class CNdefMessage;
+
+QT_BEGIN_HEADER
+
+class Proxy : public QObject
+{
+ Q_OBJECT
+public:
+ Proxy(QObject* parent = 0);
+
+Q_SIGNALS:
+ void handleMessage(const QNdefMessage& message);
+};
+
+class ContentHandlerInterface : public QObject
+{
+ Q_OBJECT
+public:
+ ContentHandlerInterface(QObject* parent = 0);
+
+public slots:
+ void handleMessage(const QByteArray& message);
+};
+
+class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivate
+{
+ Q_OBJECT
+
+public:
+ QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl();
+
+ bool isAvailable() const;
+
+ int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object, const QMetaMethod &method);
+
+ bool unregisterNdefMessageHandler(int id);
+
+ bool startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes);
+ void stopTargetDetection();
+
+public://call back function by symbian backend implementation
+ void targetFound(QNearFieldTarget* target);
+ void targetDisconnected();
+
+public://call back function by symbian backend implementation
+ void invokeNdefMessageHandler(const QNdefMessage msg);
+
+
+private slots:
+ void _q_privateHandleMessageSlot(QNdefMessage msg);
+
+private:
+ struct Callback {
+ QNdefFilter filter;
+ QObject *object;
+ QMetaMethod method;
+ };
+
+ int getFreeId();
+
+ QList<Callback> m_registeredHandlers;
+ QList<int> m_freeIds;
+
+ CNearFieldManager* m_symbianbackend;
+
+ QPointer<QNearFieldTarget> m_target;
+ QList<QPointer<QNearFieldTarget> > m_targetList;
+ //For content handler purpose;
+ QObject *m_chobject;
+ QMetaMethod m_chmethod;
+
+ QRemoteServiceRegister* m_serviceRegister ;
+};
+
+QT_END_HEADER
+#endif /* QNEARFIELDMANAGER_SYMBIAN_P_H_ */
diff --git a/src/nfc/qnearfieldmanagerimpl_p.cpp b/src/nfc/qnearfieldmanagerimpl_p.cpp
new file mode 100644
index 00000000..24609b30
--- /dev/null
+++ b/src/nfc/qnearfieldmanagerimpl_p.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+
+#include "qnearfieldmanagerimpl_p.h"
+
+
+/*
+ Constructs a new near field manager private implementation.
+*/
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
+{
+}
+
+/*
+ Destroys the near field manager private implementation.
+*/
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+}
+//#include "moc_qnearfieldmanagerimpl_p.cpp"
+
diff --git a/src/nfc/qnearfieldmanagerimpl_p.h b/src/nfc/qnearfieldmanagerimpl_p.h
new file mode 100644
index 00000000..fffcebd2
--- /dev/null
+++ b/src/nfc/qnearfieldmanagerimpl_p.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGERIMPL_P_H
+#define QNEARFIELDMANAGERIMPL_P_H
+
+#include "qnearfieldmanager_p.h"
+
+class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivate
+{
+public:
+ QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl();
+};
+
+#endif // QNEARFIELDMANAGERIMPL_P_H
diff --git a/src/nfc/qnearfieldmanagervirtualbase.cpp b/src/nfc/qnearfieldmanagervirtualbase.cpp
new file mode 100644
index 00000000..84b88f2f
--- /dev/null
+++ b/src/nfc/qnearfieldmanagervirtualbase.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanagervirtualbase_p.h"
+#include "qndefmessage.h"
+#include "qtlv_p.h"
+
+static inline bool matchesTarget(QNearFieldTarget::Type type,
+ const QList<QNearFieldTarget::Type> &types)
+{
+ return types.contains(type) || types.contains(QNearFieldTarget::AnyTarget);
+}
+
+QNearFieldManagerPrivateVirtualBase::QNearFieldManagerPrivateVirtualBase()
+{
+}
+
+QNearFieldManagerPrivateVirtualBase::~QNearFieldManagerPrivateVirtualBase()
+{
+}
+
+bool QNearFieldManagerPrivateVirtualBase::startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes)
+{
+ m_detectTargetTypes = targetTypes;
+ return true;
+}
+
+void QNearFieldManagerPrivateVirtualBase::stopTargetDetection()
+{
+ m_detectTargetTypes.clear();
+}
+
+int QNearFieldManagerPrivateVirtualBase::getFreeId()
+{
+ if (!m_freeIds.isEmpty())
+ return m_freeIds.takeFirst();
+
+ m_registeredHandlers.append(Callback());
+ return m_registeredHandlers.count() - 1;
+}
+
+int QNearFieldManagerPrivateVirtualBase::registerNdefMessageHandler(QObject *object,
+ const QMetaMethod &method)
+{
+ int id = getFreeId();
+
+ Callback &callback = m_registeredHandlers[id];
+
+ callback.filter = QNdefFilter();
+ callback.object = object;
+ callback.method = method;
+
+ return id;
+}
+
+int QNearFieldManagerPrivateVirtualBase::registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object,
+ const QMetaMethod &method)
+{
+ int id = getFreeId();
+
+ Callback &callback = m_registeredHandlers[id];
+
+ callback.filter = filter;
+ callback.object = object;
+ callback.method = method;
+
+ return id;
+}
+
+bool QNearFieldManagerPrivateVirtualBase::unregisterNdefMessageHandler(int id)
+{
+ if (id < 0 || id >= m_registeredHandlers.count())
+ return false;
+
+ m_freeIds.append(id);
+
+ while (m_freeIds.contains(m_registeredHandlers.count() - 1)) {
+ m_freeIds.removeAll(m_registeredHandlers.count() - 1);
+ m_registeredHandlers.removeLast();
+ }
+
+ return true;
+}
+
+void QNearFieldManagerPrivateVirtualBase::targetActivated(QNearFieldTarget *target)
+{
+ if (matchesTarget(target->type(), m_detectTargetTypes))
+ emit targetDetected(target);
+
+ if (target->hasNdefMessage()) {
+ QTlvReader reader(target);
+ while (!reader.atEnd()) {
+ if (!reader.readNext()) {
+ if (!target->waitForRequestCompleted(reader.requestId()))
+ break;
+ else
+ continue;
+ }
+
+ // NDEF Message TLV
+ if (reader.tag() == 0x03)
+ ndefReceived(QNdefMessage::fromByteArray(reader.data()), target);
+ }
+ }
+}
+
+void QNearFieldManagerPrivateVirtualBase::targetDeactivated(QNearFieldTarget *target)
+{
+ emit targetLost(target);
+ QMetaObject::invokeMethod(target, "disconnected");
+}
+
+struct VerifyRecord
+{
+ QNdefFilter::Record filterRecord;
+ unsigned int count;
+};
+
+void QNearFieldManagerPrivateVirtualBase::ndefReceived(const QNdefMessage &message,
+ QNearFieldTarget *target)
+{
+ for (int i = 0; i < m_registeredHandlers.count(); ++i) {
+ if (m_freeIds.contains(i))
+ continue;
+
+ Callback &callback = m_registeredHandlers[i];
+
+ bool matched = true;
+
+ QList<VerifyRecord> filterRecords;
+ for (int j = 0; j < callback.filter.recordCount(); ++j) {
+ VerifyRecord vr;
+ vr.count = 0;
+ vr.filterRecord = callback.filter.recordAt(j);
+
+ filterRecords.append(vr);
+ }
+
+ foreach (const QNdefRecord &record, message) {
+ for (int j = 0; matched && (j < filterRecords.count()); ++j) {
+ VerifyRecord &vr = filterRecords[j];
+
+ if (vr.filterRecord.typeNameFormat == record.typeNameFormat() &&
+ vr.filterRecord.type == record.type()) {
+ ++vr.count;
+ break;
+ } else {
+ if (callback.filter.orderMatch()) {
+ if (vr.filterRecord.minimum <= vr.count &&
+ vr.count <= vr.filterRecord.maximum) {
+ continue;
+ } else {
+ matched = false;
+ }
+ }
+ }
+ }
+ }
+
+ for (int j = 0; matched && (j < filterRecords.count()); ++j) {
+ const VerifyRecord &vr = filterRecords.at(j);
+
+ if (vr.filterRecord.minimum <= vr.count && vr.count <= vr.filterRecord.maximum)
+ continue;
+ else
+ matched = false;
+ }
+
+ if (matched) {
+ callback.method.invoke(callback.object, Q_ARG(QNdefMessage, message),
+ Q_ARG(QNearFieldTarget *, target));
+ }
+ }
+}
+
+#include "moc_qnearfieldmanagervirtualbase_p.cpp"
diff --git a/src/nfc/qnearfieldmanagervirtualbase_p.h b/src/nfc/qnearfieldmanagervirtualbase_p.h
new file mode 100644
index 00000000..6dac5657
--- /dev/null
+++ b/src/nfc/qnearfieldmanagervirtualbase_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGERVIRTUALBASE_P_H
+#define QNEARFIELDMANAGERVIRTUALBASE_P_H
+
+#include "qnearfieldmanager_p.h"
+
+#include <QtCore/QMetaMethod>
+
+QT_BEGIN_HEADER
+
+class QNearFieldManagerPrivateVirtualBase : public QNearFieldManagerPrivate
+{
+ Q_OBJECT
+
+public:
+ QNearFieldManagerPrivateVirtualBase();
+ ~QNearFieldManagerPrivateVirtualBase();
+
+ bool startTargetDetection(const QList<QNearFieldTarget::Type> &targetTypes);
+ void stopTargetDetection();
+
+ int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(const QNdefFilter &filter,
+ QObject *object, const QMetaMethod &method);
+
+ bool unregisterNdefMessageHandler(int id);
+
+protected:
+ struct Callback {
+ QNdefFilter filter;
+
+ QObject *object;
+ QMetaMethod method;
+ };
+
+ void targetActivated(QNearFieldTarget *target);
+ void targetDeactivated(QNearFieldTarget *target);
+
+private:
+ int getFreeId();
+ void ndefReceived(const QNdefMessage &message, QNearFieldTarget *target);
+
+ QList<Callback> m_registeredHandlers;
+ QList<int> m_freeIds;
+ QList<QNearFieldTarget::Type> m_detectTargetTypes;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDMANAGERVIRTUALBASE_P_H
diff --git a/src/nfc/qnearfieldtagmifare_symbian.cpp b/src/nfc/qnearfieldtagmifare_symbian.cpp
new file mode 100644
index 00000000..14f13205
--- /dev/null
+++ b/src/nfc/qnearfieldtagmifare_symbian.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <nfctag.h>
+#include <QVariant>
+#include "qnearfieldtagmifare_symbian_p.h"
+
+QNearFieldTagMifareSymbian::QNearFieldTagMifareSymbian(CNearFieldNdefTarget *tag, QObject *parent)
+ : QNearFieldTarget(parent), QNearFieldTagImpl(tag)
+{
+}
+
+QNearFieldTagMifareSymbian::~QNearFieldTagMifareSymbian()
+{
+}
+
+QByteArray QNearFieldTagMifareSymbian::uid() const
+{
+ return _uid();
+}
+
+bool QNearFieldTagMifareSymbian::hasNdefMessage()
+{
+ return _hasNdefMessage();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagMifareSymbian::readNdefMessages()
+{
+ return _ndefMessages();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagMifareSymbian::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ return _setNdefMessages(messages);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagMifareSymbian::sendCommand(const QByteArray &command)
+{
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagMifareSymbian::sendCommands(const QList<QByteArray> &commands)
+{
+ return _sendCommands(commands);
+}
+
+void QNearFieldTagMifareSymbian::handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted)
+{
+ Q_UNUSED(command);
+ QVariant decodedResponse = decodeResponse(command, response);
+ setResponseForRequest(id, decodedResponse, emitRequestCompleted);
+}
+
+bool QNearFieldTagMifareSymbian::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ BEGIN
+ END
+ return _waitForRequestCompleted(id, msecs);
+}
+#include "moc_qnearfieldtagmifare_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldtagmifare_symbian_p.h b/src/nfc/qnearfieldtagmifare_symbian_p.h
new file mode 100644
index 00000000..f9714e38
--- /dev/null
+++ b/src/nfc/qnearfieldtagmifare_symbian_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QNEARFIELDTAGMIFARE_H
+#define QNEARFIELDTAGMIFARE_H
+
+#include "qnearfieldtarget.h"
+#include "symbian/nearfieldndeftarget_symbian.h"
+#include "symbian/nearfieldtag_symbian.h"
+#include "symbian/nearfieldtagimpl_symbian.h"
+
+QT_BEGIN_HEADER
+
+class QNdefMessage;
+
+class QNearFieldTagMifareSymbian : public QNearFieldTarget, private QNearFieldTagImpl<QNearFieldTagMifareSymbian>
+{
+ Q_OBJECT
+
+public:
+ explicit QNearFieldTagMifareSymbian(CNearFieldNdefTarget *tag, QObject *parent = 0);
+
+ ~QNearFieldTagMifareSymbian();
+
+ QByteArray uid() const;
+
+ QNearFieldTarget::Type type() const { return QNearFieldTarget::MifareTag; }
+ QNearFieldTarget::AccessMethods accessMethods() const
+ {
+ return _accessMethods();
+ }
+
+ void setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+ {
+ _setAccessMethods(accessMethods);
+ }
+ // NdefAccess
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ // TagTypeSpecificAccess
+ RequestId sendCommand(const QByteArray &command);
+ RequestId sendCommands(const QList<QByteArray> &commands);
+ bool isProcessingCommand() const { return _isProcessingRequest(); }
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+ void handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted);
+ QVariant decodeResponse(const QByteArray &/*command*/, const QByteArray &response) { return response; }
+signals:
+ void disconnected();
+
+ friend class QNearFieldTagImpl<QNearFieldTagMifareSymbian>;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGMIFARE_H
diff --git a/src/nfc/qnearfieldtagtype1.cpp b/src/nfc/qnearfieldtagtype1.cpp
new file mode 100644
index 00000000..eb1d6c7e
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype1.cpp
@@ -0,0 +1,735 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtagtype1.h"
+#include "qnearfieldtarget_p.h"
+#include "qndefmessage.h"
+#include "qtlv_p.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QVariant>
+
+#include <QtCore/QDebug>
+
+/*!
+ \class QNearFieldTagType1
+ \brief The QNearFieldTagType1 class provides an interface for communicating with an NFC Tag
+ Type 1 tag.
+ \since 5.0
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+*/
+
+/*!
+ \enum QNearFieldTagType1::WriteMode
+ \brief This enum describes the write modes that are supported.
+
+ \value EraseAndWrite The memory is erased before the new value is written.
+ \value WriteOnly The memory is not erased before the new value is written. The effect of
+ this mode is that the final value store is the bitwise or of the data
+ to be written and the original data value.
+*/
+
+/*!
+ \fn Type QNearFieldTagType1::type() const
+ \reimp
+*/
+
+class QNearFieldTagType1Private
+{
+ Q_DECLARE_PUBLIC(QNearFieldTagType1)
+
+public:
+ QNearFieldTagType1Private(QNearFieldTagType1 *q)
+ : q_ptr(q), m_readNdefMessageState(NotReadingNdefMessage),
+ m_tlvReader(0),
+ m_writeNdefMessageState(NotWritingNdefMessage)
+ { }
+
+ QNearFieldTagType1 *q_ptr;
+
+ QMap<QNearFieldTarget::RequestId, QByteArray> m_pendingInternalCommands;
+
+ enum ReadNdefMessageState {
+ NotReadingNdefMessage,
+ NdefReadCheckingIdentification,
+ NdefReadCheckingNdefMagicNumber,
+ NdefReadReadingTlv
+ };
+
+ void progressToNextNdefReadMessageState();
+ ReadNdefMessageState m_readNdefMessageState;
+ QNearFieldTarget::RequestId m_readNdefRequestId;
+
+ QTlvReader *m_tlvReader;
+ QNearFieldTarget::RequestId m_nextExpectedRequestId;
+
+ enum WriteNdefMessageState {
+ NotWritingNdefMessage,
+ NdefWriteCheckingIdentification,
+ NdefWriteCheckingNdefMagicNumber,
+ NdefWriteReadingTlv,
+ NdefWriteWritingTlv,
+ NdefWriteWritingTlvFlush
+ };
+
+ void progressToNextNdefWriteMessageState();
+ WriteNdefMessageState m_writeNdefMessageState;
+ QNearFieldTarget::RequestId m_writeNdefRequestId;
+ QList<QNdefMessage> m_ndefWriteMessages;
+
+ QTlvWriter *m_tlvWriter;
+
+ typedef QPair<quint8, QByteArray> Tlv;
+ QList<Tlv> m_tlvs;
+};
+
+void QNearFieldTagType1Private::progressToNextNdefReadMessageState()
+{
+ Q_Q(QNearFieldTagType1);
+
+ switch (m_readNdefMessageState) {
+ case NotReadingNdefMessage:
+ m_readNdefMessageState = NdefReadCheckingIdentification;
+ m_nextExpectedRequestId = q->readIdentification();
+ break;
+ case NdefReadCheckingIdentification: {
+ const QByteArray data = q->requestResponse(m_nextExpectedRequestId).toByteArray();
+
+ if (data.isEmpty()) {
+ m_readNdefMessageState = NotReadingNdefMessage;
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+ emit q->error(QNearFieldTarget::NdefReadError, m_readNdefRequestId);
+ m_readNdefRequestId = QNearFieldTarget::RequestId();
+ break;
+ }
+
+ quint8 hr0 = data.at(0);
+
+ // Check if target is a NFC TagType1 tag
+ if (!(hr0 & 0x10)) {
+ m_readNdefMessageState = NotReadingNdefMessage;
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+ emit q->error(QNearFieldTarget::NdefReadError, m_readNdefRequestId);
+ m_readNdefRequestId = QNearFieldTarget::RequestId();
+ break;
+ }
+
+ m_readNdefMessageState = NdefReadCheckingNdefMagicNumber;
+ m_nextExpectedRequestId = q->readByte(8);
+ break;
+ }
+ case NdefReadCheckingNdefMagicNumber: {
+ quint8 ndefMagicNumber = q->requestResponse(m_nextExpectedRequestId).toUInt();
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+
+ if (ndefMagicNumber != 0xe1) {
+ m_readNdefMessageState = NotReadingNdefMessage;
+ emit q->error(QNearFieldTarget::NdefReadError, m_readNdefRequestId);
+ m_readNdefRequestId = QNearFieldTarget::RequestId();
+ break;
+ }
+
+ m_readNdefMessageState = NdefReadReadingTlv;
+ m_tlvReader = new QTlvReader(q);
+
+ // fall through
+ }
+ case NdefReadReadingTlv:
+ while (!m_tlvReader->atEnd()) {
+ if (!m_tlvReader->readNext())
+ break;
+
+ // NDEF Message TLV
+ if (m_tlvReader->tag() == 0x03) {
+ Q_Q(QNearFieldTagType1);
+
+ emit q->ndefMessageRead(QNdefMessage::fromByteArray(m_tlvReader->data()));
+ }
+ }
+
+ m_nextExpectedRequestId = m_tlvReader->requestId();
+ if (!m_nextExpectedRequestId.isValid()) {
+ delete m_tlvReader;
+ m_tlvReader = 0;
+ m_readNdefMessageState = NotReadingNdefMessage;
+ emit q->requestCompleted(m_readNdefRequestId);
+ m_readNdefRequestId = QNearFieldTarget::RequestId();
+ }
+ break;
+ }
+}
+
+void QNearFieldTagType1Private::progressToNextNdefWriteMessageState()
+{
+ Q_Q(QNearFieldTagType1);
+
+ switch (m_writeNdefMessageState) {
+ case NotWritingNdefMessage:
+ m_writeNdefMessageState = NdefWriteCheckingIdentification;
+ m_nextExpectedRequestId = q->readIdentification();
+ break;
+ case NdefWriteCheckingIdentification: {
+ const QByteArray data = q->requestResponse(m_nextExpectedRequestId).toByteArray();
+
+ if (data.isEmpty()) {
+ m_writeNdefMessageState = NotWritingNdefMessage;
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+ emit q->error(QNearFieldTarget::NdefWriteError, m_writeNdefRequestId);
+ m_writeNdefRequestId = QNearFieldTarget::RequestId();
+ break;
+ }
+
+ quint8 hr0 = data.at(0);
+
+ // Check if target is a NFC TagType1 tag
+ if (!(hr0 & 0x10)) {
+ m_writeNdefMessageState = NotWritingNdefMessage;
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+ emit q->error(QNearFieldTarget::NdefWriteError, m_writeNdefRequestId);
+ m_writeNdefRequestId = QNearFieldTarget::RequestId();
+ break;
+ }
+
+ m_writeNdefMessageState = NdefWriteCheckingNdefMagicNumber;
+ m_nextExpectedRequestId = q->readByte(8);
+ break;
+ }
+ case NdefWriteCheckingNdefMagicNumber: {
+ quint8 ndefMagicNumber = q->requestResponse(m_nextExpectedRequestId).toUInt();
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+
+ if (ndefMagicNumber != 0xe1) {
+ m_writeNdefMessageState = NotWritingNdefMessage;
+ emit q->error(QNearFieldTarget::NdefWriteError, m_writeNdefRequestId);
+ m_writeNdefRequestId = QNearFieldTarget::RequestId();
+ break;
+ }
+
+ m_writeNdefMessageState = NdefWriteReadingTlv;
+ m_tlvReader = new QTlvReader(q);
+
+ // fall through
+ }
+ case NdefWriteReadingTlv:
+ while (!m_tlvReader->atEnd()) {
+ if (!m_tlvReader->readNext())
+ break;
+
+ quint8 tag = m_tlvReader->tag();
+ if (tag == 0x01 || tag == 0x02 || tag == 0xfd)
+ m_tlvs.append(qMakePair(tag, m_tlvReader->data()));
+ }
+
+ m_nextExpectedRequestId = m_tlvReader->requestId();
+ if (m_nextExpectedRequestId.isValid())
+ break;
+
+ delete m_tlvReader;
+ m_tlvReader = 0;
+ m_writeNdefMessageState = NdefWriteWritingTlv;
+
+ // fall through
+ case NdefWriteWritingTlv:
+ m_tlvWriter = new QTlvWriter(q);
+
+ // write old TLVs
+ foreach (const Tlv &tlv, m_tlvs)
+ m_tlvWriter->writeTlv(tlv.first, tlv.second);
+
+ // write new NDEF message TLVs
+ foreach (const QNdefMessage &message, m_ndefWriteMessages)
+ m_tlvWriter->writeTlv(0x03, message.toByteArray());
+
+ // write terminator TLV
+ m_tlvWriter->writeTlv(0xfe);
+
+ m_writeNdefMessageState = NdefWriteWritingTlvFlush;
+
+ // fall through
+ case NdefWriteWritingTlvFlush:
+ // flush the writer
+ if (m_tlvWriter->process(true)) {
+ m_nextExpectedRequestId = QNearFieldTarget::RequestId();
+ m_writeNdefMessageState = NotWritingNdefMessage;
+ delete m_tlvWriter;
+ m_tlvWriter = 0;
+ emit q->ndefMessagesWritten();
+ emit q->requestCompleted(m_writeNdefRequestId);
+ m_writeNdefRequestId = QNearFieldTarget::RequestId();
+ } else {
+ m_nextExpectedRequestId = m_tlvWriter->requestId();
+ if (!m_nextExpectedRequestId.isValid()) {
+ m_writeNdefMessageState = NotWritingNdefMessage;
+ delete m_tlvWriter;
+ m_tlvWriter = 0;
+ emit q->error(QNearFieldTarget::NdefWriteError, m_writeNdefRequestId);
+ m_writeNdefRequestId = QNearFieldTarget::RequestId();
+ }
+ }
+ break;
+ }
+}
+
+static QVariant decodeResponse(const QByteArray &command, const QByteArray &response)
+{
+ switch (command.at(0)) {
+ case 0x01: // READ
+ if (command.at(1) == response.at(0))
+ return quint8(response.at(1));
+ break;
+ case 0x53: { // WRITE-E
+ quint8 address = command.at(1);
+ quint8 data = command.at(2);
+ quint8 writeAddress = response.at(0);
+ quint8 writeData = response.at(1);
+
+ return ((writeAddress == address) && (writeData == data));
+ }
+ case 0x1a: { // WRITE-NE
+ quint8 address = command.at(1);
+ quint8 data = command.at(2);
+ quint8 writeAddress = response.at(0);
+ quint8 writeData = response.at(1);
+
+ return ((writeAddress == address) && ((writeData & data) == data));
+ }
+ case 0x10: { // RSEG
+ quint8 segmentAddress = quint8(command.at(1)) >> 4;
+ quint8 readSegmentAddress = quint8(response.at(0)) >> 4;
+ if (readSegmentAddress == segmentAddress)
+ return response.mid(1);
+ break;
+ }
+ case 0x02: { // READ8
+ quint8 blockAddress = command.at(1);
+ quint8 readBlockAddress = response.at(0);
+ if (readBlockAddress == blockAddress)
+ return response.mid(1);
+ break;
+ }
+ case 0x54: { // WRITE-E8
+ quint8 blockAddress = command.at(1);
+ QByteArray data = command.mid(2, 8);
+ quint8 writeBlockAddress = response.at(0);
+ QByteArray writeData = response.mid(1);
+
+ return ((writeBlockAddress == blockAddress) && (writeData == data));
+ }
+ case 0x1b: { // WRITE-NE8
+ quint8 blockAddress = command.at(1);
+ QByteArray data = command.mid(2, 8);
+ quint8 writeBlockAddress = response.at(0);
+ QByteArray writeData = response.mid(1);
+
+ if (writeBlockAddress != blockAddress)
+ return false;
+
+ for (int i = 0; i < writeData.length(); ++i) {
+ if ((writeData.at(i) & data.at(i)) != data.at(i))
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ return QVariant();
+}
+
+/*!
+ Constructs a new tag type 1 near field target with \a parent.
+*/
+QNearFieldTagType1::QNearFieldTagType1(QObject *parent)
+: QNearFieldTarget(parent), d_ptr(new QNearFieldTagType1Private(this))
+{
+}
+
+/*!
+ Destroys the tag type 1 near field target.
+*/
+QNearFieldTagType1::~QNearFieldTagType1()
+{
+ delete d_ptr;
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType1::hasNdefMessage()
+{
+ RequestId id = readAll();
+ if (!waitForRequestCompleted(id))
+ return false;
+
+ const QByteArray data = requestResponse(id).toByteArray();
+
+ if (data.isEmpty())
+ return false;
+
+ quint8 hr0 = data.at(0);
+
+ // Check if target is a NFC TagType1 tag
+ if (!(hr0 & 0x10))
+ return false;
+
+ // Check if NDEF Message Magic number is present
+ quint8 nmn = data.at(10);
+ if (nmn != 0xe1)
+ return false;
+
+ // Check if TLV contains NDEF Message
+ return true;
+}
+
+/*!
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::readNdefMessages()
+{
+ Q_D(QNearFieldTagType1);
+
+ d->m_readNdefRequestId = RequestId(new RequestIdPrivate);
+
+ if (d->m_readNdefMessageState == QNearFieldTagType1Private::NotReadingNdefMessage) {
+ d->progressToNextNdefReadMessageState();
+ } else {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, NdefReadError),
+ Q_ARG(QNearFieldTarget::RequestId, d->m_readNdefRequestId));
+ }
+
+ return d->m_readNdefRequestId;
+}
+
+/*!
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ Q_D(QNearFieldTagType1);
+
+ d->m_writeNdefRequestId = RequestId(new RequestIdPrivate);
+
+ if (d->m_readNdefMessageState == QNearFieldTagType1Private::NotReadingNdefMessage &&
+ d->m_writeNdefMessageState == QNearFieldTagType1Private::NotWritingNdefMessage) {
+ d->m_ndefWriteMessages = messages;
+ d->progressToNextNdefWriteMessageState();
+ } else {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, NdefWriteError),
+ Q_ARG(QNearFieldTarget::RequestId, d->m_readNdefRequestId));
+ }
+
+ return d->m_writeNdefRequestId;
+}
+
+/*!
+ Returns the NFC Tag Type 1 specification version number that the tag supports.
+*/
+quint8 QNearFieldTagType1::version()
+{
+ RequestId id = readByte(9);
+ if (!waitForRequestCompleted(id))
+ return 0;
+
+ quint8 versionNumber = requestResponse(id).toUInt();
+ return versionNumber;
+}
+
+/*!
+ Returns the memory size in bytes of the tag.
+*/
+int QNearFieldTagType1::memorySize()
+{
+ RequestId id = readByte(10);
+ if (!waitForRequestCompleted(id))
+ return 0;
+
+ quint8 tms = requestResponse(id).toUInt();
+
+ return 8 * (tms + 1);
+}
+
+/*!
+ Requests the identification bytes from the target. Returns a request id which can be used to
+ track the completion status of the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray containing: HR0,
+ HR1, UID0, UID1, UID2 and UID3 in order.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::readIdentification()
+{
+ QByteArray command;
+ command.append(char(0x78)); // RID
+ command.append(char(0x00)); // Address (unused)
+ command.append(char(0x00)); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ return sendCommand(command);
+}
+
+/*!
+ Requests all data in the static memory area of the target. Returns a request id which can be
+ used to track the completion status of the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray containing: HR0
+ and HR1 followed by the 120 bytes of data stored in the static memory area of the target.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::readAll()
+{
+ QByteArray command;
+ command.append(char(0x00)); // RALL
+ command.append(char(0x00)); // Address (unused)
+ command.append(char(0x00)); // Data (unused)
+ command.append(uid().left(4));// 4 bytes of UID
+
+ return sendCommand(command);
+}
+
+/*!
+ Requests a single byte from the static memory area of the tag. The \a address parameter
+ specifices the linear byte address to read. Returns a request id which can be used to track
+ the completion status of the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a quint8.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::readByte(quint8 address)
+{
+ if (address & 0x80)
+ return RequestId();
+
+ QByteArray command;
+ command.append(char(0x01)); // READ
+ command.append(char(address)); // Address
+ command.append(char(0x00)); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType1);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ return id;
+}
+
+/*!
+ Writes a single \a data byte to the linear byte \a address on the tag. If \a mode is
+ EraseAndWrite the byte will be erased before writing. If \a mode is WriteOnly the contents will
+ not be erased before writing. This is equivelant to writing the result of the bitwise OR of
+ \a data and the original value.
+
+ Returns a request id which can be used to track the completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::writeByte(quint8 address, quint8 data,
+ WriteMode mode)
+{
+ if (address & 0x80)
+ return RequestId();
+
+ QByteArray command;
+
+ if (mode == EraseAndWrite)
+ command.append(char(0x53)); // WRITE-E
+ else if (mode == WriteOnly)
+ command.append(char(0x1a)); // WRITE-NE
+ else
+ return RequestId();
+
+ command.append(char(address)); // Address
+ command.append(char(data)); // Data
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType1);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ return id;
+}
+
+/*!
+ Requests 128 bytes of data from the segment specified by \a segmentAddress. Returns a request
+ id which can be used to track the completion status of the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::readSegment(quint8 segmentAddress)
+{
+ if (segmentAddress & 0xf0)
+ return RequestId();
+
+ QByteArray command;
+ command.append(char(0x10)); // RSEG
+ command.append(char(segmentAddress << 4)); // Segment address
+ command.append(QByteArray(8, char(0x00))); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType1);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ return id;
+}
+
+/*!
+ Requests 8 bytes of data from the block specified by \a blockAddress. Returns a request id
+ which can be used to track the completion status of the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::readBlock(quint8 blockAddress)
+{
+ QByteArray command;
+ command.append(char(0x02)); // READ8
+ command.append(char(blockAddress)); // Block address
+ command.append(QByteArray(8, char(0x00))); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType1);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ return id;
+}
+
+/*!
+ Writes 8 bytes of \a data to the block specified by \a blockAddress. If \a mode is
+ EraseAndWrite the bytes will be erased before writing. If \a mode is WriteOnly the contents
+ will not be erased before writing. This is equivelant to writing the result of the bitwise OR
+ of \a data and the original value.
+
+ Returns a request id which can be used to track the completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1::writeBlock(quint8 blockAddress,
+ const QByteArray &data,
+ WriteMode mode)
+{
+ if (data.length() != 8)
+ return RequestId();
+
+ QByteArray command;
+
+ if (mode == EraseAndWrite)
+ command.append(char(0x54)); // WRITE-E8
+ else if (mode == WriteOnly)
+ command.append(char(0x1b)); // WRITE-NE8
+ else
+ return RequestId();
+
+ command.append(char(blockAddress)); // Block address
+ command.append(data); // Data
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType1);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ return id;
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType1::handleResponse(const QNearFieldTarget::RequestId &id,
+ const QByteArray &response)
+{
+ Q_D(QNearFieldTagType1);
+
+ bool handled;
+
+ if (d->m_pendingInternalCommands.contains(id)) {
+ const QByteArray command = d->m_pendingInternalCommands.take(id);
+
+ QVariant decodedResponse = decodeResponse(command, response);
+ setResponseForRequest(id, decodedResponse);
+
+ handled = true;
+ } else {
+ handled = QNearFieldTarget::handleResponse(id, response);
+ }
+
+ // continue reading / writing NDEF message
+ if (d->m_nextExpectedRequestId == id) {
+ if (d->m_readNdefMessageState != QNearFieldTagType1Private::NotReadingNdefMessage)
+ d->progressToNextNdefReadMessageState();
+ else if (d->m_writeNdefMessageState != QNearFieldTagType1Private::NotWritingNdefMessage)
+ d->progressToNextNdefWriteMessageState();
+ }
+
+ return handled;
+}
+
+#include "moc_qnearfieldtagtype1.cpp"
diff --git a/src/nfc/qnearfieldtagtype1.h b/src/nfc/qnearfieldtagtype1.h
new file mode 100644
index 00000000..f925fda3
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype1.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE1_H
+#define QNEARFIELDTAGTYPE1_H
+
+#include <qnearfieldtarget.h>
+
+QT_BEGIN_HEADER
+
+class QNearFieldTagType1Private;
+
+class Q_CONNECTIVITY_EXPORT QNearFieldTagType1 : public QNearFieldTarget
+{
+ Q_OBJECT
+
+ Q_DECLARE_PRIVATE(QNearFieldTagType1)
+
+public:
+ enum WriteMode {
+ EraseAndWrite,
+ WriteOnly
+ };
+
+ explicit QNearFieldTagType1(QObject *parent = 0);
+ ~QNearFieldTagType1();
+
+ Type type() const { return NfcTagType1; }
+
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ quint8 version();
+ virtual int memorySize();
+
+ // DIGPROTO
+ virtual RequestId readIdentification();
+
+ // static memory functions
+ virtual RequestId readAll();
+ virtual RequestId readByte(quint8 address);
+ virtual RequestId writeByte(quint8 address, quint8 data, WriteMode mode = EraseAndWrite);
+
+ // dynamic memory functions
+ virtual RequestId readSegment(quint8 segmentAddress);
+ virtual RequestId readBlock(quint8 blockAddress);
+ virtual RequestId writeBlock(quint8 blockAddress, const QByteArray &data,
+ WriteMode mode = EraseAndWrite);
+
+protected:
+ bool handleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &response);
+
+private:
+ QNearFieldTagType1Private *d_ptr;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGTYPE1_H
diff --git a/src/nfc/qnearfieldtagtype1_symbian.cpp b/src/nfc/qnearfieldtagtype1_symbian.cpp
new file mode 100644
index 00000000..fc7be21a
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype1_symbian.cpp
@@ -0,0 +1,402 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <nfctag.h>
+#include <QVariant>
+#include "symbian/nearfieldutility_symbian.h"
+#include "qnearfieldtagtype1_symbian_p.h"
+#include "debug.h"
+
+//#define SYMBIAN_BUG_NOT_FIX
+
+static void OutputByteArray(const QByteArray& data)
+{
+ for(int i = 0; i < data.count(); ++i)
+ {
+ LOG("data ["<<i<<"] = "<<((quint16)(data.at(i))));
+ }
+}
+
+QVariant QNearFieldTagType1Symbian::decodeResponse(const QByteArray &command, const QByteArray &response)
+{
+ BEGIN
+ OutputByteArray(response);
+ END
+ switch (command.at(0)) {
+ case 0x01: // READ
+#ifndef SYMBIAN_BUG_NOT_FIX
+ if (command.at(1) == response.at(0))
+ return quint8(response.at(1));
+ break;
+#else
+ return quint8(response.at(0));
+#endif
+ case 0x53: { // WRITE-E
+#ifndef SYMBIAN_BUG_NOT_FIX
+ quint8 address = command.at(1);
+ quint8 data = command.at(2);
+ quint8 writeAddress = response.at(0);
+ quint8 writeData = response.at(1);
+ return ((writeAddress == address) && (writeData == data));
+#else
+ quint8 data = command.at(2);
+
+ quint8 writeData = response.at(0);
+ return (writeData == data);
+#endif
+ }
+ case 0x1a: { // WRITE-NE
+#ifndef SYMBIAN_BUG_NOT_FIX
+ quint8 address = command.at(1);
+ quint8 data = command.at(2);
+ quint8 writeAddress = response.at(0);
+ quint8 writeData = response.at(1);
+
+ return ((writeAddress == address) && ((writeData & data) == data));
+#else
+ quint8 data = command.at(2);
+ quint8 writeData = response.at(0);
+ return ((writeData & data) == data);
+#endif
+ }
+ case 0x10: { // RSEG
+#ifndef SYMBIAN_BUG_NOT_FIX
+ quint8 segmentAddress = quint8(command.at(1)) >> 4;
+ quint8 readSegmentAddress = quint8(response.at(0)) >> 4;
+ if (readSegmentAddress == segmentAddress)
+ return response.mid(1);
+ break;
+#else
+ return response;
+#endif
+ }
+ case 0x02: { // READ8
+#ifndef SYMBIAN_BUG_NOT_FIX
+ quint8 blockAddress = command.at(1);
+ quint8 readBlockAddress = response.at(0);
+ if (readBlockAddress == blockAddress)
+ return response.mid(1);
+ break;
+#else
+ return response;
+#endif
+ }
+ case 0x54: { // WRITE-E8
+#ifndef SYMBIAN_BUG_NOT_FIX
+ quint8 blockAddress = command.at(1);
+ QByteArray data = command.mid(2, 8);
+ quint8 writeBlockAddress = response.at(0);
+ QByteArray writeData = response.mid(1);
+
+ return ((writeBlockAddress == blockAddress) && (writeData == data));
+#else
+ QByteArray data = command.mid(2, 8);
+
+ return (response == data);
+#endif
+ }
+ case 0x1b: { // WRITE-NE8
+#ifndef SYMBIAN_BUG_NOT_FIX
+ quint8 blockAddress = command.at(1);
+ QByteArray data = command.mid(2, 8);
+ quint8 writeBlockAddress = response.at(0);
+ QByteArray writeData = response.mid(1);
+
+ if (writeBlockAddress != blockAddress)
+ return false;
+
+ for (int i = 0; i < writeData.length(); ++i) {
+ if ((writeData.at(i) & data.at(i)) != data.at(i))
+ return false;
+ }
+ return true;
+#else
+ QByteArray data = command.mid(2, 8);
+ QByteArray writeData = response;
+
+ for (int i = 0; i < writeData.length(); ++i) {
+ if ((writeData.at(i) & data.at(i)) != data.at(i))
+ return false;
+ }
+ return true;
+#endif
+ }
+ }
+
+ return response;
+}
+/*
+ \class QNearFieldTagType1Symbian
+ \brief The QNearFieldTagType1Symbian class provides symbian backend implementation for communicating with an NFC Tag
+ Type 1 tag.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+*/
+
+/*
+ Constructs a new tag type 1 near field target with \a tag and \a parent.
+*/
+QNearFieldTagType1Symbian::QNearFieldTagType1Symbian(CNearFieldNdefTarget *tag, QObject *parent)
+ : QNearFieldTagType1(parent), QNearFieldTagImpl(tag)
+{
+}
+
+/*
+ Destructor
+*/
+QNearFieldTagType1Symbian::~QNearFieldTagType1Symbian()
+{
+}
+
+QByteArray QNearFieldTagType1Symbian::uid() const
+{
+ return _uid();
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::readIdentification()
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x78)); // RID
+ command.append(char(0x00)); // Address (unused)
+ command.append(char(0x00)); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+ END
+ return sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::readAll()
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x00)); // RALL
+ command.append(char(0x00));
+ command.append(char(0x00));
+ command.append(uid().left(4)); // UID
+ END
+ return sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::readByte(quint8 address)
+{
+ BEGIN
+ // MSB must be 0
+ if (address & 0x80)
+ return QNearFieldTarget::RequestId();
+
+ QByteArray command;
+ command.append(char(0x01)); // READ
+ command.append(char(address)); // Address
+ command.append(char(0x00)); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ END
+ return sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::writeByte(quint8 address, quint8 data, WriteMode mode)
+{
+ BEGIN
+ // MSB must be 0
+ if (address & 0x80)
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+
+ QByteArray command;
+
+ if (mode == EraseAndWrite)
+ command.append(char(0x53)); // WRITE-E
+ else
+ command.append(char(0x1a)); // WRITE-NE
+
+ command.append(char(address)); // Address
+ command.append(char(data)); // Data
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ END
+ return sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::readSegment(quint8 segmentAddress)
+{
+ BEGIN
+ if (segmentAddress & 0xf0)
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+
+ QByteArray command;
+ command.append(char(0x10)); // RSEG
+ command.append(char(segmentAddress << 4)); // Segment address
+ command.append(QByteArray(8, char(0x00))); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UIDD
+
+ END
+ return sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::readBlock(quint8 blockAddress)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x02)); // READ8
+ command.append(char(blockAddress)); // Block address
+ command.append(QByteArray(8, char(0x00))); // Data (unused)
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ END
+ return sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::writeBlock(quint8 blockAddress, const QByteArray &data,
+ WriteMode mode)
+{
+ BEGIN
+ if (data.length() != 8)
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+
+ QByteArray command;
+
+ if (mode == EraseAndWrite)
+ command.append(char(0x54)); // WRITE-E8
+ else
+ command.append(char(0x1b)); // WRITE-NE8
+
+ command.append(char(blockAddress)); // Block address
+ command.append(data); // Data
+ command.append(uid().left(4)); // 4 bytes of UID
+
+ END
+ return sendCommand(command);
+}
+
+bool QNearFieldTagType1Symbian::hasNdefMessage()
+{
+ return _hasNdefMessage();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::readNdefMessages()
+{
+ BEGIN
+ END
+ return _ndefMessages();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ BEGIN
+ END
+ return _setNdefMessages(messages);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::sendCommand(const QByteArray &command)
+{
+ BEGIN
+ END
+ return _sendCommand(command);
+}
+
+/*
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType1Symbian::sendCommands(const QList<QByteArray> &commands)
+{
+ BEGIN
+ END
+ return _sendCommands(commands);
+}
+
+bool QNearFieldTagType1Symbian::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ BEGIN
+ END
+ return _waitForRequestCompleted(id, msecs);
+}
+
+void QNearFieldTagType1Symbian::handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted)
+{
+ BEGIN
+ QVariant decodedResponse;
+ if (!response.isNull())
+ {
+ decodedResponse = decodeResponse(command, response);
+ }
+ else
+ {
+ decodedResponse = response;
+ }
+
+ setResponseForRequest(id, decodedResponse, emitRequestCompleted);
+ END
+}
+
+#include "moc_qnearfieldtagtype1_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldtagtype1_symbian_p.h b/src/nfc/qnearfieldtagtype1_symbian_p.h
new file mode 100644
index 00000000..cfcdbe70
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype1_symbian_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE1SYMBIAN_H
+#define QNEARFIELDTAGTYPE1SYMBIAN_H
+
+#include <qnearfieldtagtype1.h>
+#include "symbian/nearfieldndeftarget_symbian.h"
+#include "symbian/nearfieldtag_symbian.h"
+#include "symbian/nearfieldtagimpl_symbian.h"
+
+QT_BEGIN_HEADER
+
+class QNearFieldTagType1Symbian : public QNearFieldTagType1, private QNearFieldTagImpl<QNearFieldTagType1Symbian>
+{
+ Q_OBJECT
+
+public:
+
+ explicit QNearFieldTagType1Symbian(CNearFieldNdefTarget *tag, QObject *parent = 0);
+
+ ~QNearFieldTagType1Symbian();
+
+ virtual QByteArray uid() const;
+
+ // DIGPROTO
+ RequestId readIdentification();
+
+ // static memory functions
+ RequestId readAll();
+ RequestId readByte(quint8 address);
+ RequestId writeByte(quint8 address, quint8 data, WriteMode mode = EraseAndWrite);
+
+ // dynamic memory functions
+ RequestId readSegment(quint8 segmentAddress);
+ RequestId readBlock(quint8 blockAddress);
+ RequestId writeBlock(quint8 blockAddress, const QByteArray &data,
+ WriteMode mode = EraseAndWrite);
+
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ bool isProcessingCommand() const { return _isProcessingRequest(); }
+ RequestId sendCommand(const QByteArray &command);
+ RequestId sendCommands(const QList<QByteArray> &commands);
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+ void setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+ {
+ _setAccessMethods(accessMethods);
+ }
+
+ QNearFieldTarget::AccessMethods accessMethods() const
+ {
+ return _accessMethods();
+ }
+
+ void handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted);
+ QVariant decodeResponse(const QByteArray &command, const QByteArray &response);
+ friend class QNearFieldTagImpl<QNearFieldTagType1Symbian>;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGTYPE1SYMBIAN_H
diff --git a/src/nfc/qnearfieldtagtype2.cpp b/src/nfc/qnearfieldtagtype2.cpp
new file mode 100644
index 00000000..f54567ec
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype2.cpp
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtagtype2.h"
+#include "qnearfieldtarget_p.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTime>
+
+#include <QtCore/QDebug>
+
+/*!
+ \class QNearFieldTagType2
+ \brief The QNearFieldTagType2 class provides an interface for communicating with an NFC Tag
+ Type 2 tag.
+ \since 5.0
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+*/
+
+/*!
+ \fn Type QNearFieldTagType2::type() const
+ \reimp
+*/
+
+struct SectorSelectState {
+ int timerId; // id of timer used for passive ack
+ quint8 sector; // sector being selected
+};
+
+class QNearFieldTagType2Private
+{
+public:
+ QNearFieldTagType2Private() : m_currentSector(0) { }
+
+ QMap<QNearFieldTarget::RequestId, QByteArray> m_pendingInternalCommands;
+
+ quint8 m_currentSector;
+
+ QMap<QNearFieldTarget::RequestId, SectorSelectState> m_pendingSectorSelectCommands;
+};
+
+static QVariant decodeResponse(const QByteArray &command, const QByteArray &response)
+{
+ quint8 opcode = command.at(0);
+
+ switch (opcode) {
+ case 0xa2: // WRITE
+ return quint8(response.at(0)) == 0x0a;
+ case 0xc2: // SECTOR SELECT (Command Packet 1)
+ return quint8(response.at(0)) == 0x0a;
+ }
+
+ return QVariant();
+}
+
+/*!
+ Constructs a new tag type 2 near field target with \a parent.
+*/
+QNearFieldTagType2::QNearFieldTagType2(QObject *parent)
+: QNearFieldTarget(parent), d_ptr(new QNearFieldTagType2Private)
+{
+}
+
+/*!
+ Destroys the tag type 2 near field target.
+*/
+QNearFieldTagType2::~QNearFieldTagType2()
+{
+ delete d_ptr;
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType2::hasNdefMessage()
+{
+ qDebug() << Q_FUNC_INFO << "is unimplemeted";
+ return false;
+}
+
+/*!
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType2::readNdefMessages()
+{
+ return RequestId();
+}
+
+/*!
+ \reimp
+*/
+QNearFieldTarget::RequestId QNearFieldTagType2::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ Q_UNUSED(messages);
+
+ return RequestId();
+}
+
+/*!
+ Returns the NFC Tag Type 2 specification version number that the tag supports.
+*/
+quint8 QNearFieldTagType2::version()
+{
+ Q_D(QNearFieldTagType2);
+ if (d->m_currentSector != 0) {
+ RequestId id = selectSector(0);
+ if (!waitForRequestCompleted(id))
+ return 0;
+ }
+
+ RequestId id = readBlock(0);
+ if (!waitForRequestCompleted(id))
+ return 0;
+
+ const QByteArray data = requestResponse(id).toByteArray();
+ return data.at(13);
+}
+
+/*!
+ Returns the memory size in bytes of the tag.
+*/
+int QNearFieldTagType2::memorySize()
+{
+ Q_D(QNearFieldTagType2);
+ if (d->m_currentSector != 0) {
+ RequestId id = selectSector(0);
+ if (!waitForRequestCompleted(id))
+ return 0;
+ }
+
+ RequestId id = readBlock(0);
+ if (!waitForRequestCompleted(id))
+ return 0;
+
+ const QByteArray data = requestResponse(id).toByteArray();
+ return 8 * quint8(data.at(14));
+}
+
+/*!
+ Requests 16 bytes of data starting at \a blockAddress. Returns a request id which can be used
+ to track the completion status of the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType2::readBlock(quint8 blockAddress)
+{
+ QByteArray command;
+ command.append(char(0x30)); // READ
+ command.append(char(blockAddress)); // Block address
+
+ return sendCommand(command);
+}
+
+/*!
+ Writes 4 bytes of \a data to the block at \a blockAddress. Returns a request id which can be
+ used to track the completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ Returns true on success; otherwise returns false.
+*/
+QNearFieldTarget::RequestId QNearFieldTagType2::writeBlock(quint8 blockAddress,
+ const QByteArray &data)
+{
+ if (data.length() != 4)
+ return RequestId();
+
+ QByteArray command;
+ command.append(char(0xa2)); // WRITE
+ command.append(char(blockAddress)); // Block address
+ command.append(data); // Data
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType2);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ return id;
+}
+
+/*!
+ Selects the \a sector upon which subsequent readBlock() and writeBlock() operations will act.
+
+ Returns a request id which can be used to track the completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \note this request has a passive acknowledgement mechanism. The operation is deemed successful
+ if no response is received within 1ms. It will therefore take a minimum of 1 millisecond for
+ the requestCompleted() signal to be emitted and calling waitForRequestCompleted() on the
+ returned request id may cause the current thread to block for up to 1 millisecond.
+*/
+QNearFieldTarget::RequestId QNearFieldTagType2::selectSector(quint8 sector)
+{
+ QByteArray command;
+ command.append(char(0xc2)); // SECTOR SELECT (Command Packet 1)
+ command.append(char(0xff));
+
+ RequestId id = sendCommand(command);
+
+ Q_D(QNearFieldTagType2);
+
+ d->m_pendingInternalCommands.insert(id, command);
+
+ SectorSelectState state;
+ state.timerId = -1;
+ state.sector = sector;
+
+ d->m_pendingSectorSelectCommands.insert(id, state);
+
+ return id;
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType2::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ Q_D(QNearFieldTagType2);
+
+ QTime timer;
+ timer.start();
+ while (d->m_pendingSectorSelectCommands.contains(id)) {
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents, 1);
+
+ // detect passive ack
+ if (timer.elapsed() >= 1)
+ break;
+ }
+
+ return QNearFieldTarget::waitForRequestCompleted(id, msecs);
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType2::handleResponse(const QNearFieldTarget::RequestId &id,
+ const QByteArray &response)
+{
+ Q_D(QNearFieldTagType2);
+
+ if (d->m_pendingInternalCommands.contains(id)) {
+ const QByteArray command = d->m_pendingInternalCommands.take(id);
+
+ QVariant decodedResponse = decodeResponse(command, response);
+ if (quint8(command.at(0)) == 0xc2 && decodedResponse.toBool()) {
+ // SECTOR SELECT (Command Packet 2)
+ SectorSelectState &state = d->m_pendingSectorSelectCommands[id];
+
+ QByteArray packet2;
+ packet2.append(char(state.sector));
+ packet2.append(QByteArray(3, 0x00));
+
+ sendCommand(packet2);
+
+ state.timerId = startTimer(1);
+ } else {
+ setResponseForRequest(id, decodedResponse);
+ }
+
+ return true;
+ } else if (d->m_pendingSectorSelectCommands.contains(id)) {
+ if (!response.isEmpty()) {
+ d->m_pendingSectorSelectCommands.remove(id);
+ setResponseForRequest(id, false);
+
+ return true;
+ }
+ }
+
+ return QNearFieldTarget::handleResponse(id, response);
+}
+
+/*!
+ \internal
+*/
+void QNearFieldTagType2::timerEvent(QTimerEvent *event)
+{
+ Q_D(QNearFieldTagType2);
+
+ killTimer(event->timerId());
+
+ QMutableMapIterator<QNearFieldTarget::RequestId, SectorSelectState> i(d->m_pendingSectorSelectCommands);
+ while (i.hasNext()) {
+ i.next();
+
+ SectorSelectState &state = i.value();
+
+ if (state.timerId == event->timerId()) {
+ d->m_currentSector = state.sector;
+
+ setResponseForRequest(i.key(), true);
+
+ i.remove();
+
+ break;
+ }
+ }
+}
+
+#include "moc_qnearfieldtagtype2.cpp"
diff --git a/src/nfc/qnearfieldtagtype2.h b/src/nfc/qnearfieldtagtype2.h
new file mode 100644
index 00000000..ad83fe8b
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype2.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE2_H
+#define QNEARFIELDTAGTYPE2_H
+
+#include <qnearfieldtarget.h>
+
+QT_BEGIN_HEADER
+
+class QNearFieldTagType2Private;
+
+class Q_CONNECTIVITY_EXPORT QNearFieldTagType2 : public QNearFieldTarget
+{
+ Q_OBJECT
+
+ Q_DECLARE_PRIVATE(QNearFieldTagType2)
+
+public:
+ explicit QNearFieldTagType2(QObject *parent = 0);
+ ~QNearFieldTagType2();
+
+ Type type() const { return NfcTagType2; }
+
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ quint8 version();
+ int memorySize();
+
+ virtual RequestId readBlock(quint8 blockAddress);
+ virtual RequestId writeBlock(quint8 blockAddress, const QByteArray &data);
+ virtual RequestId selectSector(quint8 sector);
+
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+ void timerEvent(QTimerEvent *event);
+
+protected:
+ bool handleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &response);
+
+private:
+ QNearFieldTagType2Private *d_ptr;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGTYPE2_H
diff --git a/src/nfc/qnearfieldtagtype2_symbian.cpp b/src/nfc/qnearfieldtagtype2_symbian.cpp
new file mode 100644
index 00000000..adac6370
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype2_symbian.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <nfctag.h>
+#include <QVariant>
+#include "qnearfieldtagtype2_symbian_p.h"
+#include <qnearfieldtarget_p.h>
+
+//#define SYMBIAN_NEED_CRC
+//#define SYMBIAN_RETURN_CRC
+//#define SYMBIAN_RETURN_NO_ACK
+
+static void OutputByteArray(const QByteArray& data)
+{
+ for(int i = 0; i < data.count(); ++i)
+ {
+ LOG("data ["<<i<<"] = "<<((quint16)(data.at(i))));
+ }
+}
+
+QNearFieldTagType2Symbian::QNearFieldTagType2Symbian(CNearFieldNdefTarget *tag, QObject *parent)
+ : QNearFieldTagType2(parent), QNearFieldTagImpl(tag), mCurrentSector(0)
+{
+}
+
+QNearFieldTagType2Symbian::~QNearFieldTagType2Symbian()
+{
+ BEGIN
+ END
+}
+
+QVariant QNearFieldTagType2Symbian::decodeResponse(const QByteArray& command, const QByteArray& response)
+{
+ BEGIN
+ OutputByteArray(response);
+
+ QVariant result;
+ switch(command.at(0))
+ {
+ case 0x30:
+ {
+ // read command
+#ifdef SYMBIAN_RETURN_CRC
+ result = response.left(16);
+#else
+ result = response;
+#endif
+ break;
+ }
+ case 0xA2:
+ {
+#ifdef SYMBIAN_RETURN_NO_ACK
+ result = true;
+#else
+ // write command
+ result = (response.at(0) == 0x0A);
+#endif
+ break;
+ }
+ default:
+ {
+#ifdef SYMBIAN_RETURN_CRC
+ result = response.left(16);
+#else
+ result = response;
+#endif
+ }
+ }
+ END
+ return result;
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::readBlock(quint8 blockAddress)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x30)); // READ
+ command.append(char(blockAddress)); // Block address
+
+#ifdef SYMBIAN_NEED_CRC
+ // append CRC
+ quint16 crc = qNfcChecksum(command.constData(), command.count());
+ command.append((unsigned char)(crc&0xFF));
+ command.append((unsigned char)((crc>>8)&0xFF));
+#endif
+ END
+ return sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::writeBlock(quint8 blockAddress, const QByteArray &data)
+{
+ BEGIN
+ if (data.length() != 4)
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ QByteArray command;
+ command.append(char(0xa2)); // WRITE
+ command.append(char(blockAddress)); // Block address
+ command.append(data); // Data
+
+#ifdef SYMBIAN_NEED_CRC
+ // append CRC
+ quint16 crc = qNfcChecksum(command.constData(), command.count());
+ command.append((unsigned char)(crc&0xFF));
+ command.append((unsigned char)((crc>>8)&0xFF));
+#endif
+
+ END
+ return sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::selectSector(quint8 sector)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0xc2)); // SECTOR SELECT (Command Packet 1)
+ command.append(char(0xff));
+
+#ifdef SYMBIAN_NEED_CRC
+ // append CRC
+ quint16 crc = qNfcChecksum(command.constData(), command.count());
+ command.append((unsigned char)(crc&0xFF));
+ command.append((unsigned char)((crc>>8)&0xFF));
+#endif
+
+ RequestId id = sendCommand(command);
+
+ if (!_waitForRequestCompletedNoSignal(id, 1))
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ else
+ {
+ command.clear();
+ command.append(char(sector)); // Sector number
+ command.append(QByteArray(3, char(0x00))); // RFU
+#ifdef SYMBIAN_NEED_CRC
+ // append CRC
+ quint16 crc = qNfcChecksum(command.constData(), command.count());
+ command.append((unsigned char)(crc&0xFF));
+ command.append((unsigned char)((crc>>8)&0xFF));
+#endif
+ END
+ return sendCommand(command);
+ }
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::sendCommand(const QByteArray &command)
+{
+ BEGIN
+ END
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::sendCommands(const QList<QByteArray> &commands)
+{
+ BEGIN
+ END
+ return _sendCommands(commands);
+}
+
+bool QNearFieldTagType2Symbian::hasNdefMessage()
+{
+ return _hasNdefMessage();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::readNdefMessages()
+{
+ BEGIN
+ END
+ return _ndefMessages();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType2Symbian::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ BEGIN
+ END
+ return _setNdefMessages(messages);
+}
+
+QByteArray QNearFieldTagType2Symbian::uid() const
+{
+ BEGIN
+ END
+ return _uid();
+}
+
+void QNearFieldTagType2Symbian::handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted)
+{
+ BEGIN
+ Q_UNUSED(command);
+ QVariant decodedResponse = decodeResponse(command, response);
+ setResponseForRequest(id, decodedResponse, emitRequestCompleted);
+ END
+}
+
+bool QNearFieldTagType2Symbian::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ BEGIN
+ END
+ return _waitForRequestCompleted(id, msecs);
+}
+
+#include "moc_qnearfieldtagtype2_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldtagtype2_symbian_p.h b/src/nfc/qnearfieldtagtype2_symbian_p.h
new file mode 100644
index 00000000..10ac6066
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype2_symbian_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE2SYMBIAN_H
+#define QNEARFIELDTAGTYPE2SYMBIAN_H
+
+#include <qnearfieldtagtype2.h>
+#include "symbian/nearfieldndeftarget_symbian.h"
+#include "symbian/nearfieldtag_symbian.h"
+#include "symbian/nearfieldtagimpl_symbian.h"
+
+QT_BEGIN_HEADER
+
+class QNearFieldTagType2Symbian : public QNearFieldTagType2, private QNearFieldTagImpl<QNearFieldTagType2Symbian>
+{
+ Q_OBJECT
+public:
+ explicit QNearFieldTagType2Symbian(CNearFieldNdefTarget * tag, QObject *parent = 0);
+
+ ~QNearFieldTagType2Symbian();
+
+ QByteArray uid() const;
+
+ RequestId readBlock(quint8 blockAddress);
+ RequestId writeBlock(quint8 blockAddress, const QByteArray &data);
+ RequestId selectSector(quint8 sector);
+
+ RequestId sendCommand(const QByteArray &command);
+ RequestId sendCommands(const QList<QByteArray> &commands);
+ bool isProcessingCommand() const { return _isProcessingRequest(); }
+
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ void setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+ {
+ _setAccessMethods(accessMethods);
+ }
+
+ QNearFieldTarget::AccessMethods accessMethods() const
+ {
+ return _accessMethods();
+ }
+
+ void handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted);
+ QVariant decodeResponse(const QByteArray &command, const QByteArray &response);
+
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+ friend class QNearFieldTagImpl<QNearFieldTagType2Symbian>;
+
+private:
+ quint8 mCurrentSector;
+};
+
+QT_END_HEADER
+
+#endif //QNEARFIELDTAGTYPE2SYMBIAN_H
diff --git a/src/nfc/qnearfieldtagtype3.cpp b/src/nfc/qnearfieldtagtype3.cpp
new file mode 100644
index 00000000..2c751b09
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype3.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtagtype3.h"
+
+/*!
+ \class QNearFieldTagType3
+ \brief The QNearFieldTagType3 class provides an interface for communicating with an NFC Tag
+ Type 3 tag.
+ \since 5.0
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+*/
+
+/*!
+ \fn Type QNearFieldTagType3::type() const
+ \reimp
+*/
+
+/*!
+ Constructs a new tag type 3 near field target with \a parent.
+*/
+QNearFieldTagType3::QNearFieldTagType3(QObject *parent) :
+ QNearFieldTarget(parent)
+{
+}
+
+/*!
+ Returns the system code of the target.
+*/
+quint16 QNearFieldTagType3::systemCode()
+{
+ return 0;
+}
+
+/*!
+ Returns a list of available services.
+*/
+QList<quint16> QNearFieldTagType3::services()
+{
+ return QList<quint16>();
+}
+
+/*!
+ Returns the memory size of the service specified by \a serviceCode.
+*/
+int QNearFieldTagType3::serviceMemorySize(quint16 serviceCode)
+{
+ Q_UNUSED(serviceCode);
+
+ return 0;
+}
+
+/*!
+ Requests the data contents of the service specified by \a serviceCode. Returns a request id
+ which can be used to track the completion status of the request.
+
+ Once the request completes successfully the service data can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType3::serviceData(quint16 serviceCode)
+{
+ Q_UNUSED(serviceCode);
+
+ return RequestId();
+}
+
+/*!
+ Writes \a data to the the service specified by \a serviceCode. Returns a request id which can
+ be used to track the completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType3::writeServiceData(quint16 serviceCode,
+ const QByteArray &data)
+{
+ Q_UNUSED(serviceCode);
+ Q_UNUSED(data);
+
+ return RequestId();
+}
+
+/*!
+ Sends the \i check request to the target. Requests the service data blocks specified by
+ \a serviceBlockList. Returns a request id which can be used to track the completion status of
+ the request.
+
+ The \a serviceBlockList parameter is a map with the key being the service code and the value
+ being a list of block indexes to retrieve.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a QMap<quint16, QByteArray>, with the key being the
+ service code and the value being the concatenated blocks retrieved for that service.
+
+ This is a low level function, to retrieve the entire data contents of a service use
+ serviceData().
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType3::check(const QMap<quint16, QList<quint16> > &serviceBlockList)
+{
+ Q_UNUSED(serviceBlockList);
+
+ return RequestId();
+}
+
+/*!
+ Sends the \i update request to the target. Writes \a data to the services and block indexes
+ sepecified by \a serviceBlockList. Returns a request id which can be used to track the
+ completion status of the request.
+
+ The \a serviceBlockList parameter is a map with the key being the service code and the value
+ being a list of block indexes to write to.
+
+ Once the request completes the response can be retried from the requestResponse() function. The
+ response of this request will be a boolean value, true for success; otherwise false.
+
+ This is a low level function, to write the entire data contents of a service use
+ writeServiceData().
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType3::update(const QMap<quint16, QList<quint16> > &serviceBlockList,
+ const QByteArray &data)
+{
+ Q_UNUSED(serviceBlockList);
+ Q_UNUSED(data);
+
+ return RequestId();
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType3::handleResponse(const QNearFieldTarget::RequestId &id,
+ const QByteArray &response)
+{
+ return QNearFieldTarget::handleResponse(id, response);
+}
+
+#include "moc_qnearfieldtagtype3.cpp"
diff --git a/src/nfc/qnearfieldtagtype3.h b/src/nfc/qnearfieldtagtype3.h
new file mode 100644
index 00000000..7ab9721d
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype3.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE3_H
+#define QNEARFIELDTAGTYPE3_H
+
+#include <qnearfieldtarget.h>
+
+#include <QtCore/QList>
+#include <QtCore/QMap>
+
+QT_BEGIN_HEADER
+
+class Q_CONNECTIVITY_EXPORT QNearFieldTagType3 : public QNearFieldTarget
+{
+ Q_OBJECT
+
+public:
+ explicit QNearFieldTagType3(QObject *parent = 0);
+
+ Type type() const { return NfcTagType3; }
+
+ quint16 systemCode();
+ QList<quint16> services();
+ int serviceMemorySize(quint16 serviceCode);
+
+ virtual RequestId serviceData(quint16 serviceCode);
+ virtual RequestId writeServiceData(quint16 serviceCode, const QByteArray &data);
+
+ virtual RequestId check(const QMap<quint16, QList<quint16> > &serviceBlockList);
+ virtual RequestId update(const QMap<quint16, QList<quint16> > &serviceBlockList,
+ const QByteArray &data);
+
+protected:
+ bool handleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &response);
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGTYPE3_H
diff --git a/src/nfc/qnearfieldtagtype3_symbian.cpp b/src/nfc/qnearfieldtagtype3_symbian.cpp
new file mode 100644
index 00000000..b7c66a6a
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype3_symbian.cpp
@@ -0,0 +1,504 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <nfctag.h>
+#include "qnearfieldtagtype3_symbian_p.h"
+#include <nfctype3connection.h>
+#include <QtEndian>
+#include <QVariant>
+
+/* For all #if 0 blocks: this is due to symbian RawModeAccess API is not
+ * available yet. After the RawModeAccess API is stable, those blocks
+ * should be enabled.
+ */
+
+#define SYMBIAN_RESP_INCLUDE_LEN
+
+static void OutputByteArray(const QByteArray& data)
+{
+ for(int i = 0; i < data.count(); ++i)
+ {
+ LOG("data ["<<i<<"] = "<<((quint16)(data.at(i))));
+ }
+}
+
+static void OutputCmdMap(const QMap<quint16, QList<quint16> >& data)
+{
+ QList<quint16> mapKeys = data.keys();
+ for(int i = 0; i < mapKeys.count(); ++i)
+ {
+ LOG("cmd Map key "<<mapKeys.at(i)<<" value "<<data.value(mapKeys.at(i)));
+ }
+}
+
+static void OutputRspMap(const QMap<quint16, QByteArray>& data)
+{
+ QList<quint16> mapKeys = data.keys();
+ for(int i = 0; i < mapKeys.count(); ++i)
+ {
+ LOG("rsp Map key "<<mapKeys.at(i));
+ OutputByteArray(data.value(mapKeys.at(i)));
+ }
+}
+
+QNearFieldTagType3Symbian::QNearFieldTagType3Symbian(CNearFieldNdefTarget *tag, QObject *parent)
+ : QNearFieldTagType3(parent), QNearFieldTagImpl(tag)
+{
+ // It's silly, but easy.
+ getIDm();
+}
+
+QNearFieldTagType3Symbian::~QNearFieldTagType3Symbian()
+{
+}
+
+QByteArray QNearFieldTagType3Symbian::uid() const
+{
+ return _uid();
+}
+
+QVariant QNearFieldTagType3Symbian::decodeResponse(const QByteArray & command, const QByteArray &response)
+{
+ BEGIN
+ OutputByteArray(response);
+#ifndef SYMBIAN_RESP_INCLUDE_LEN
+ QVariant result;
+ if (command.count() < 0)
+ {
+ END;
+ return result;
+ }
+
+ switch(command.at(0))
+ {
+ case 0x06:
+ {
+ // check command
+ result.setValue(checkResponse2ServiceBlockList(cmd2ServiceBlockList(command), response));
+ break;
+ }
+ case 0x08:
+ {
+ result = (response.at(9) == 0);
+ break;
+ }
+ default:
+ {
+ result = response;
+ }
+
+ }
+ END
+#else
+ QVariant result;
+ if (command.count() < 0)
+ {
+ END;
+ return result;
+ }
+ QByteArray newResponse = response.right(response.count() - 1);
+ switch(command.at(0))
+ {
+ case 0x06:
+ {
+ // check command
+ result.setValue(checkResponse2ServiceBlockList(cmd2ServiceBlockList(command), newResponse));
+ break;
+ }
+ case 0x08:
+ {
+ result = (newResponse.at(9) == 0);
+ break;
+ }
+ default:
+ {
+ result = newResponse;
+ }
+ }
+ END
+#endif
+ return result;
+}
+
+bool QNearFieldTagType3Symbian::hasNdefMessage()
+{
+#if 0
+ BEGIN
+ bool hasNdef = false;
+ QList<quint16> blockList;
+ // first block
+ blockList.append(0);
+ // NDEF service
+ quint16 serviceCode = 0x0B;
+
+ QMap<quint16, QList<quint16> > serviceBlockList;
+ serviceBlockList.insert(serviceCode, blockList);
+
+ QNearFieldTarget::RequestId id = check(serviceBlockList);
+
+ if (_waitForRequestCompletedNoSignal(id))
+ {
+ QMap<quint16, QByteArray> result = requestResponse(id).value<QMap<quint16, QByteArray> >();
+ if (result.contains(serviceCode))
+ {
+ const QByteArray& lens = result.value(serviceCode);
+ if (!lens.isEmpty())
+ {
+ quint32 len = lens.at(11);
+ len<<=8;
+ len |= lens.at(12);
+ len<<=8;
+ len |= lens.at(13);
+ hasNdef = (len > 0);
+ }
+ }
+ }
+ END
+ return hasNdef;
+#endif
+ return _hasNdefMessage();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::readNdefMessages()
+{
+ return _ndefMessages();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ return _setNdefMessages(messages);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::sendCommand(const QByteArray &command)
+{
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::sendCommands(const QList<QByteArray> &commands)
+{
+ return _sendCommands(commands);
+}
+
+#if 0
+quint16 QNearFieldTagType3Symbian::systemCode()
+{
+ return 0;
+}
+
+QList<quint16> QNearFieldTagType3Symbian::services()
+{
+ return QList<quint16>();
+}
+
+int QNearFieldTagType3Symbian::serviceMemorySize(quint16 serviceCode)
+{
+ Q_UNUSED(serviceCode);
+ return 0;
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::serviceData(quint16 serviceCode)
+{
+ Q_UNUSED(serviceCode);
+ return QNearFieldTarget::RequestId();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::writeServiceData(quint16 serviceCode, const QByteArray &data)
+{
+ Q_UNUSED(serviceCode);
+ Q_UNUSED(data);
+
+ return RequestId();
+}
+#endif
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::check(const QMap<quint16, QList<quint16> > &serviceBlockList)
+{
+ BEGIN
+ quint8 numberOfBlocks;
+ QByteArray command;
+ command.append(0x06); // command code
+ command.append(serviceBlockList2CmdParam(serviceBlockList, numberOfBlocks, true));
+ if (command.count() > 1)
+ {
+ END
+ return (_sendCommand(command));
+ }
+ else
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType3Symbian::update(const QMap<quint16, QList<quint16> > &serviceBlockList, const QByteArray &data)
+{
+ BEGIN
+ quint8 numberOfBlocks;
+ QByteArray command;
+ command.append(0x08); // command code
+ command.append(serviceBlockList2CmdParam(serviceBlockList, numberOfBlocks, false));
+ if (command.count() > 1)
+ {
+ command.append(data);
+ END
+ return (_sendCommand(command));
+ }
+ else
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+}
+
+const QByteArray& QNearFieldTagType3Symbian::getIDm()
+{
+ BEGIN
+ if (mIDm.isEmpty())
+ {
+ // this is the first time to get IDm
+ CNearFieldTag * tag = mTag->CastToTag();
+
+ if (tag)
+ {
+ CNfcType3Connection * connection = static_cast<CNfcType3Connection *>(tag->TagConnection());
+ TBuf8<8> IDm;
+ TInt error = connection->GetIDm(IDm);
+ if (KErrNone == error)
+ {
+ mIDm = QNFCNdefUtility::TDesC2QByteArray(IDm);
+ }
+ }
+ }
+ OutputByteArray(mIDm);
+ END
+ return mIDm;
+}
+
+QByteArray QNearFieldTagType3Symbian::serviceBlockList2CmdParam(const QMap<quint16, QList<quint16> > &serviceBlockList, quint8& numberOfBlocks, bool isCheckCommand)
+{
+ BEGIN
+ OutputCmdMap(serviceBlockList);
+ QByteArray command;
+ command.append(getIDm());
+ numberOfBlocks = 0;
+
+ if (command.isEmpty())
+ {
+ // can't get IDm
+ END
+ return command;
+ }
+
+ quint8 numberOfServices = serviceBlockList.keys().count();
+
+ if ((numberOfServices > 16) || (numberOfServices < 1))
+ {
+ // out of range of services number
+ END
+ return QByteArray();
+ }
+ else
+ {
+ command.append(numberOfServices);
+ }
+
+ quint8 serviceCodeListOrder = 0;
+ QByteArray serviceCodeList;
+ QByteArray blockList;
+ foreach(const quint16 serviceCode, serviceBlockList.keys())
+ {
+ serviceCodeList.append(reinterpret_cast<const char *>(&serviceCode), sizeof(quint16));
+
+ numberOfBlocks += serviceBlockList.value(serviceCode).count();
+ LOG("numberOfBlocks "<<numberOfBlocks)
+ if ( (isCheckCommand && (numberOfBlocks > 12)) ||
+ (!isCheckCommand && (numberOfBlocks > 8)) )
+ {
+ // out of range of block number
+ LOG("out of range of block number");
+ END
+ return QByteArray();
+ }
+
+ foreach(const quint16 blockNumber, serviceBlockList.value(serviceCode))
+ {
+ if (blockNumber > 255)
+ {
+ // 3 bytes format
+ blockList.append(0x00 | (serviceCodeListOrder & 0x0F));
+ quint16 blkNum = blockNumber;
+ blkNum = qToLittleEndian(blkNum);
+ blockList.append(reinterpret_cast<const char *>(&blkNum), sizeof(quint16));
+ }
+ else // 2 bytes format
+ {
+ blockList.append(0x80 | (serviceCodeListOrder & 0x0F));
+ quint8 blkNum = blockNumber;
+ blockList.append(blkNum);
+ }
+ }
+ }
+
+ if (numberOfBlocks < 1)
+ {
+ // out of range of block number
+ LOG("out of range of block number, number of blocks < 1");
+ END
+ return QByteArray();
+ }
+
+ command.append(serviceCodeList);
+ command.append(numberOfBlocks);
+ command.append(blockList);
+ OutputByteArray(command);
+ END
+ return command;
+}
+
+QMap<quint16, QList<quint16> > QNearFieldTagType3Symbian::cmd2ServiceBlockList(const QByteArray& cmd)
+{
+ BEGIN
+ QMap<quint16, QList<quint16> > result;
+ // skip command code and IDm
+ QByteArray data = cmd.right(cmd.count() - 9);
+
+ quint8 numberOfServices = data.at(0);
+
+ QByteArray serviceCodeList = data.mid(1, 2 * numberOfServices);
+
+ quint8 numberOfBlocks = data.at(2 * numberOfServices + 1);
+
+ QByteArray blockList = data.right(data.count() - 1 - 2*numberOfServices - 1);
+
+ QList<quint16> svcList;
+ for (int i = 0; i < numberOfServices; ++i)
+ {
+ unsigned char bytes[2];
+ bytes[0] = serviceCodeList.at(i*2);
+ bytes[1] = serviceCodeList.at(i*2+1);
+ quint16 serviceCode = qFromLittleEndian<quint16>(bytes);
+ svcList.append(serviceCode);
+ }
+
+ for (int j = 0, k = 0; j < numberOfBlocks; ++j, ++k)
+ {
+ quint8 byte0 = blockList.at(k);
+ quint8 serviceCodeListOrder = byte0 & 0x0F;
+ quint16 blockNumber = 0;
+
+ if (byte0 & 0x80)
+ {
+ // two bytes format
+ blockNumber = blockList.at(++k);
+ }
+ else
+ {
+ // three bytes format
+ unsigned char bytes[2];
+ bytes[0] = blockList.at(++k);
+ bytes[1] = blockList.at(++k);
+ blockNumber = qFromLittleEndian<quint16>(bytes);
+ }
+
+ if (result.contains(svcList.at(serviceCodeListOrder)))
+ {
+ result[svcList.at(serviceCodeListOrder)].append(blockNumber);
+ }
+ else
+ {
+ QList<quint16> blocks;
+ blocks.append(blockNumber);
+ result.insert(svcList.at(serviceCodeListOrder), blocks);
+ }
+ }
+
+ OutputCmdMap(result);
+
+ END
+ return result;
+}
+
+QMap<quint16, QByteArray> QNearFieldTagType3Symbian::checkResponse2ServiceBlockList(const QMap<quint16, QList<quint16> > &serviceBlockList, const QByteArray& response)
+{
+ BEGIN
+ OutputCmdMap(serviceBlockList);
+ QMap<quint16, QByteArray> result;
+ // at least, the response should contain resp code + IDM + status flags
+ if (response.count() < 11)
+ {
+ END
+ return result;
+ }
+
+ if ((response.at(0) != 0x07) || (response.mid(1,8) != getIDm()) || (response.at(10) != 0))
+ {
+ END
+ return result;
+ }
+
+ quint32 index = 12;
+ foreach(const quint16 serviceCode, serviceBlockList.keys())
+ {
+ quint8 blockCount = serviceBlockList.value(serviceCode).count();
+ result.insert(serviceCode, response.mid(index, 16*blockCount));
+ index+=16*blockCount;
+ }
+ OutputRspMap(result);
+ END
+ return result;
+}
+
+
+void QNearFieldTagType3Symbian::handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted)
+{
+ Q_UNUSED(command);
+ QVariant decodedResponse = decodeResponse(command, response);
+ setResponseForRequest(id, decodedResponse, emitRequestCompleted);
+}
+
+bool QNearFieldTagType3Symbian::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ BEGIN
+ END
+ return _waitForRequestCompleted(id, msecs);
+}
+
+#include "moc_qnearfieldtagtype3_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldtagtype3_symbian_p.h b/src/nfc/qnearfieldtagtype3_symbian_p.h
new file mode 100644
index 00000000..a726ae8b
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype3_symbian_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE3SYMBIAN_H
+#define QNEARFIELDTAGTYPE3SYMBIAN_H
+
+#include <qnearfieldtagtype3.h>
+#include "symbian/nearfieldtagimpl_symbian.h"
+#include "symbian/nearfieldndeftarget_symbian.h"
+
+QT_BEGIN_HEADER
+
+class QNearFieldTagType3Symbian : public QNearFieldTagType3, private QNearFieldTagImpl<QNearFieldTagType3Symbian>
+{
+ Q_OBJECT
+public:
+
+ explicit QNearFieldTagType3Symbian(CNearFieldNdefTarget *tag, QObject *parent = 0);
+
+ ~QNearFieldTagType3Symbian();
+
+ virtual QByteArray uid() const;
+
+ void setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+ {
+ _setAccessMethods(accessMethods);
+ }
+
+ QNearFieldTarget::AccessMethods accessMethods() const
+ {
+ return _accessMethods();
+ }
+
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+#if 0
+ quint16 systemCode();
+ QList<quint16> services();
+ int serviceMemorySize(quint16 serviceCode);
+
+
+ RequestId serviceData(quint16 serviceCode);
+ RequestId writeServiceData(quint16 serviceCode, const QByteArray &data);
+#endif
+
+ RequestId check(const QMap<quint16, QList<quint16> > &serviceBlockList);
+ RequestId update(const QMap<quint16, QList<quint16> > &serviceBlockList,
+ const QByteArray &data);
+
+ bool isProcessingCommand() const { return _isProcessingRequest(); }
+ RequestId sendCommand(const QByteArray &command);
+ RequestId sendCommands(const QList<QByteArray> &commands);
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+private:
+ const QByteArray& getIDm();
+ QByteArray serviceBlockList2CmdParam(const QMap<quint16, QList<quint16> > &serviceBlockList, quint8& numberOfBlocks, bool isCheckCommand);
+ QMap<quint16, QList<quint16> > cmd2ServiceBlockList(const QByteArray& cmd);
+
+ QMap<quint16, QByteArray> checkResponse2ServiceBlockList(const QMap<quint16, QList<quint16> > &serviceBlockList, const QByteArray& response);
+
+ void handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted);
+ QVariant decodeResponse(const QByteArray & command, const QByteArray &response);
+private:
+ QByteArray mIDm;
+ friend class QNearFieldTagImpl<QNearFieldTagType3Symbian>;
+};
+
+typedef QMap<quint16,QByteArray> checkResponseType;
+Q_DECLARE_METATYPE(checkResponseType)
+QT_END_HEADER
+#endif // QNEARFIELDTAGTYPE3SYMBIAN_H
+
diff --git a/src/nfc/qnearfieldtagtype4.cpp b/src/nfc/qnearfieldtagtype4.cpp
new file mode 100644
index 00000000..19cf8b80
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype4.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtagtype4.h"
+
+/*!
+ \class QNearFieldTagType4
+ \brief The QNearFieldTagType4 class provides an interface for communicating with an NFC Tag
+ Type 4 tag.
+ \since 5.0
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+*/
+
+/*!
+ \fn Type QNearFieldTagType4::type() const
+ \reimp
+*/
+
+/*!
+ Constructs a new tag type 4 near field target with \a parent.
+*/
+QNearFieldTagType4::QNearFieldTagType4(QObject *parent)
+: QNearFieldTarget(parent)
+{
+}
+
+/*!
+ Destroys the tag type 4 near field target.
+*/
+QNearFieldTagType4::~QNearFieldTagType4()
+{
+}
+
+/*!
+ Returns the NFC Tag Type 4 specification version number that the tag supports.
+*/
+quint8 QNearFieldTagType4::version()
+{
+ return 0;
+}
+
+/*!
+ Requests that the file specified by \a name be selected. Upon success calls to read() and
+ write() will act on the selected file. Returns a request id which can be used to track the
+ completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType4::select(const QByteArray &name)
+{
+ Q_UNUSED(name);
+
+ return RequestId();
+}
+
+/*!
+ Requests that the file specified by \a fileIdentifier be selected. Upon success calls to read()
+ and write() will act on the selected file. Returns a request id which can be used to track the
+ completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType4::select(quint16 fileIdentifier)
+{
+ Q_UNUSED(fileIdentifier);
+
+ return RequestId();
+}
+
+/*!
+ Requests that \a length bytes be read from the currently selected file starting from
+ \a startOffset. If \a length is 0 all data or the maximum read size bytes will be read,
+ whichever is smaller. Returns a request id which can be used to track the completion status of
+ the request.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType4::read(quint16 length, quint16 startOffset)
+{
+ Q_UNUSED(length);
+ Q_UNUSED(startOffset);
+
+ return RequestId();
+}
+
+/*!
+ Writes \a data to the currently selected file starting at \a startOffset. Returns a request id
+ which can be used to track the completion status of the request.
+
+ Once the request completes the response can be retrieved from the requestResponse() function.
+ The response of this request will be a boolean value, true for success; otherwise false.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTagType4::write(const QByteArray &data, quint16 startOffset)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(startOffset);
+
+ return RequestId();
+}
+
+/*!
+ \reimp
+*/
+bool QNearFieldTagType4::handleResponse(const QNearFieldTarget::RequestId &id,
+ const QByteArray &response)
+{
+ return QNearFieldTarget::handleResponse(id, response);
+}
+
+#include "moc_qnearfieldtagtype4.cpp"
diff --git a/src/nfc/qnearfieldtagtype4.h b/src/nfc/qnearfieldtagtype4.h
new file mode 100644
index 00000000..d280580c
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype4.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE4_H
+#define QNEARFIELDTAGTYPE4_H
+
+#include <qnearfieldtarget.h>
+
+QT_BEGIN_HEADER
+
+class Q_CONNECTIVITY_EXPORT QNearFieldTagType4 : public QNearFieldTarget
+{
+ Q_OBJECT
+
+public:
+ explicit QNearFieldTagType4(QObject *parent = 0);
+ ~QNearFieldTagType4();
+
+ Type type() const { return NfcTagType4; }
+
+ quint8 version();
+
+ virtual RequestId select(const QByteArray &name);
+ virtual RequestId select(quint16 fileIdentifier);
+
+ virtual RequestId read(quint16 length = 0, quint16 startOffset = 0);
+ virtual RequestId write(const QByteArray &data, quint16 startOffset = 0);
+
+protected:
+ bool handleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &response);
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGTYPE4_H
diff --git a/src/nfc/qnearfieldtagtype4_symbian.cpp b/src/nfc/qnearfieldtagtype4_symbian.cpp
new file mode 100644
index 00000000..b1940b62
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype4_symbian.cpp
@@ -0,0 +1,396 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <nfctag.h>
+#include <QVariant>
+#include <QtEndian>
+#include "symbian/nearfieldutility_symbian.h"
+#include "qnearfieldtagtype4_symbian_p.h"
+
+static void OutputByteArray(const QByteArray& data)
+{
+ for(int i = 0; i < data.count(); ++i)
+ {
+ LOG("data ["<<i<<"] = "<<((quint16)(data.at(i))));
+ }
+}
+
+QNearFieldTagType4Symbian::QNearFieldTagType4Symbian(CNearFieldNdefTarget *tag, QObject *parent)
+ : QNearFieldTagType4(parent), QNearFieldTagImpl(tag)
+{
+}
+
+QNearFieldTagType4Symbian::~QNearFieldTagType4Symbian()
+{
+}
+
+QByteArray QNearFieldTagType4Symbian::uid() const
+{
+ return _uid();
+}
+
+quint8 QNearFieldTagType4Symbian::version()
+{
+ BEGIN
+ quint8 result = 0;
+ QByteArray resp;
+ resp.append(char(0x90));
+ resp.append(char(0x00));
+
+ QNearFieldTarget::RequestId id = selectNdefApplication();
+ if (_waitForRequestCompletedNoSignal(id))
+ {
+ if (requestResponse(id).toByteArray().right(2) == resp)
+ {
+ // response is ok
+ // select cc
+ LOG("select cc");
+ QNearFieldTarget::RequestId id1 = selectCC();
+ if (_waitForRequestCompletedNoSignal(id1))
+ {
+ if (requestResponse(id1).toBool())
+ {
+ // response is ok
+ // read cc
+ LOG("read cc");
+ QNearFieldTarget::RequestId id2 = read(0x0001,0x0002);
+ if (_waitForRequestCompletedNoSignal(id2))
+ {
+ if (requestResponse(id2).toByteArray().right(2) == resp)
+ {
+ // response is ok
+ result = requestResponse(id2).toByteArray().at(0);
+ }
+ }
+ }
+ }
+ }
+ }
+ LOG("version is "<<result);
+ END
+ return result;
+}
+
+QVariant QNearFieldTagType4Symbian::decodeResponse(const QByteArray &command, const QByteArray &response)
+{
+ BEGIN
+ QVariant result;
+
+ OutputByteArray(response);
+ if ((command.count() > 2) && (0x00 == command.at(0)))
+ {
+ if ( (0xA4 == command.at(1)) || (0xD6 == command.at(1)) )
+ {
+ if (response.count() >= 2)
+ {
+ LOG("select or write command");
+ QByteArray resp = response.right(2);
+ result = ((resp.at(0) == 0x90) && (resp.at(1) == 0x00));
+ }
+ }
+ else
+ {
+ LOG("read command");
+ result = response;
+ }
+ }
+ END
+ return result;
+}
+
+bool QNearFieldTagType4Symbian::hasNdefMessage()
+{
+ BEGIN
+ QByteArray resp;
+ resp.append(char(0x90));
+ resp.append(char(0x00));
+
+ QNearFieldTarget::RequestId id = selectNdefApplication();
+ if (!_waitForRequestCompletedNoSignal(id))
+ {
+ LOG("select NDEF application failed");
+ END
+ return false;
+ }
+
+ if (!requestResponse(id).toBool())
+ {
+ LOG("select NDEF application response is not ok");
+ END
+ return false;
+ }
+
+ QNearFieldTarget::RequestId id1 = selectCC();
+ if (!_waitForRequestCompletedNoSignal(id1))
+ {
+ LOG("select CC failed");
+ END
+ return false;
+ }
+
+ if (!requestResponse(id1).toBool())
+ {
+ LOG("select CC response is not ok");
+ END
+ return false;
+ }
+
+ QNearFieldTarget::RequestId id2 = read(0x000F,0x0000);
+ if (!_waitForRequestCompletedNoSignal(id2))
+ {
+ LOG("read CC failed");
+ END
+ return false;
+ }
+
+ QByteArray ccContent = requestResponse(id2).toByteArray();
+ if (ccContent.right(2) != resp)
+ {
+ LOG("read CC response is "<<ccContent.right(2));
+ END
+ return false;
+ }
+
+ if ((ccContent.count() != (15 + 2)) && (ccContent.at(1) != 0x0F))
+ {
+ LOG("CC is invalid"<<ccContent);
+ END
+ return false;
+ }
+
+ quint8 temp = ccContent.at(9);
+ quint16 fileId = 0;
+ fileId |= temp;
+ fileId<<=8;
+
+ temp = ccContent.at(10);
+ fileId |= temp;
+
+ temp = ccContent.at(11);
+ quint16 maxNdefLen = 0;
+ maxNdefLen |= temp;
+ maxNdefLen<<=8;
+
+ temp = ccContent.at(12);
+ maxNdefLen |= temp;
+
+ QNearFieldTarget::RequestId id3 = select(fileId);
+ if (!_waitForRequestCompletedNoSignal(id3))
+ {
+ LOG("select NDEF failed");
+ END
+ return false;
+ }
+ if (!requestResponse(id3).toBool())
+ {
+ END
+ return false;
+ }
+
+ QNearFieldTarget::RequestId id4 = read(0x0002, 0x0000);
+ if (!_waitForRequestCompletedNoSignal(id4))
+ {
+ LOG("read NDEF failed");
+ END
+ return false;
+ }
+ QByteArray ndefContent = requestResponse(id4).toByteArray();
+ if (ndefContent.right(2) != resp)
+ {
+ LOG("read NDEF response is "<<ndefContent.right(2));
+ END
+ return false;
+ }
+
+ if (ndefContent.count() != (2 + 2))
+ {
+ LOG("ndef content invalid");
+ END
+ return false;
+ }
+
+ temp = ndefContent.at(0);
+ quint16 nLen = 0;
+ nLen |= temp;
+ nLen<<=8;
+
+ temp = ndefContent.at(1);
+ nLen |= temp;
+
+ END
+ return ( (nLen > 0) && (nLen < maxNdefLen -2) );
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::readNdefMessages()
+{
+ return _ndefMessages();
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ return _setNdefMessages(messages);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::sendCommand(const QByteArray &command)
+{
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::sendCommands(const QList<QByteArray> &commands)
+{
+ return _sendCommands(commands);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::select(const QByteArray &name)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x00)); // CLA
+ command.append(char(0xA4)); // INS
+ command.append(char(0x04)); // P1, select by name
+ command.append(char(0x00)); // First or only occurrence
+ command.append(char(0x07)); // Lc
+ command.append(name);
+ END
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::select(quint16 fileIdentifier)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x00)); // CLA
+ command.append(char(0xA4)); // INS
+ command.append(char(0x00)); // P1, select by file identifier
+ command.append(char(0x00)); // First or only occurrence
+ command.append(char(0x02)); // Lc
+ quint16 temp = qToBigEndian<quint16>(fileIdentifier);
+ command.append(reinterpret_cast<const char*>(&temp),
+ sizeof(quint16));
+
+ END
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::read(quint16 length, quint16 startOffset)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x00)); // CLA
+ command.append(char(0xB0)); // INS
+ quint16 temp = qToBigEndian<quint16>(startOffset);
+ command.append(reinterpret_cast<const char*>(&temp),
+ sizeof(quint16)); // P1/P2 offset
+ /*temp = qToBigEndian<quint16>(length);
+ command.append(reinterpret_cast<const char*>(&temp),
+ sizeof(quint16)); // Le*/
+ command.append((quint8)length);
+
+ END
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::write(const QByteArray &data, quint16 startOffset)
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0x00)); // CLA
+ command.append(char(0xD6)); // INS
+ quint16 temp = qToBigEndian<quint16>(startOffset);
+ command.append(reinterpret_cast<const char *>(&temp), sizeof(quint16));
+ quint16 length = data.count();
+ if ((length > 0xFF) || (length < 0x01))
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ else
+ {
+ /*quint16 temp = qToBigEndian<quint16>(length);
+ command.append(reinterpret_cast<const char *>(&temp),
+ sizeof(quint16));*/
+ command.append((quint8)length);
+ }
+
+ command.append(data);
+ END
+ return _sendCommand(command);
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::selectNdefApplication()
+{
+ BEGIN
+ QByteArray command;
+ command.append(char(0xD2));
+ command.append(char(0x76));
+ command.append(char(0x00));
+ command.append(char(0x00));
+ command.append(char(0x85));
+ command.append(char(0x01));
+ command.append(char(0x00));
+ QNearFieldTarget::RequestId id = select(command);
+ END
+ return id;
+}
+
+QNearFieldTarget::RequestId QNearFieldTagType4Symbian::selectCC()
+{
+ BEGIN
+ END
+ return select(0xe103);
+}
+
+void QNearFieldTagType4Symbian::handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted)
+{
+ BEGIN
+ Q_UNUSED(command);
+ QVariant decodedResponse = decodeResponse(command, response);
+ setResponseForRequest(id, decodedResponse, emitRequestCompleted);
+ END
+}
+
+bool QNearFieldTagType4Symbian::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ BEGIN
+ END
+ return _waitForRequestCompleted(id, msecs);
+}
+#include "moc_qnearfieldtagtype4_symbian_p.cpp"
diff --git a/src/nfc/qnearfieldtagtype4_symbian_p.h b/src/nfc/qnearfieldtagtype4_symbian_p.h
new file mode 100644
index 00000000..6bf8bf59
--- /dev/null
+++ b/src/nfc/qnearfieldtagtype4_symbian_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGTYPE4SYMBIAN_H
+#define QNEARFIELDTAGTYPE4SYMBIAN_H
+
+#include <qnearfieldtagtype4.h>
+#include "symbian/nearfieldndeftarget_symbian.h"
+#include "symbian/nearfieldtag_symbian.h"
+#include "symbian/nearfieldtagimpl_symbian.h"
+#include "symbian/debug.h"
+
+QT_BEGIN_HEADER
+
+class QNearFieldTagType4Symbian : public QNearFieldTagType4, private QNearFieldTagImpl<QNearFieldTagType4Symbian>
+{
+ Q_OBJECT
+
+public:
+
+ explicit QNearFieldTagType4Symbian(CNearFieldNdefTarget *tag, QObject *parent = 0);
+
+ ~QNearFieldTagType4Symbian();
+
+ virtual QByteArray uid() const;
+ Type type() const { return NfcTagType4; }
+ quint8 version();
+
+ bool hasNdefMessage();
+ RequestId readNdefMessages();
+ RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ RequestId sendCommand(const QByteArray &command);
+ RequestId sendCommands(const QList<QByteArray> &commands);
+
+ RequestId select(const QByteArray &name);
+ RequestId select(quint16 fileIdentifier);
+
+ RequestId read(quint16 length = 0, quint16 startOffset = 0);
+ RequestId write(const QByteArray &data, quint16 startOffset = 0);
+ bool isProcessingCommand() const { return _isProcessingRequest(); }
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+ void setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+ {
+ _setAccessMethods(accessMethods);
+ }
+
+ QNearFieldTarget::AccessMethods accessMethods() const
+ {
+ return _accessMethods();
+ }
+
+ void handleTagOperationResponse(const RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted);
+ QVariant decodeResponse(const QByteArray &command, const QByteArray &response);
+
+private:
+ RequestId selectNdefApplication();
+ RequestId selectCC();
+
+ friend class QNearFieldTagImpl<QNearFieldTagType4Symbian>;
+};
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTAGTYPE4SYMBIAN_H
diff --git a/src/nfc/qnearfieldtarget.cpp b/src/nfc/qnearfieldtarget.cpp
new file mode 100644
index 00000000..8a7d25bc
--- /dev/null
+++ b/src/nfc/qnearfieldtarget.cpp
@@ -0,0 +1,464 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtarget.h"
+#include "qnearfieldtarget_p.h"
+#include "qndefmessage.h"
+
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+
+#include <QtCore/QDebug>
+
+/*!
+ \class QNearFieldTarget
+ \brief The QNearFieldTarget class provides an interface for communicating with a target
+ device.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+
+ QNearFieldTarget provides a generic interface for communicating with an NFC target device.
+ Both NFC Forum devices and NFC Forum Tag targets are supported by this class. All target
+ specific classes subclass this class.
+
+ The type() function can be used to get the type of the target device. The uid() function
+ returns the unique identifier of the target. The AccessMethods flags returns from the
+ accessMethods() function can be tested to determine which access methods are supported by the
+ target.
+
+ If the target supports NdefAccess, hasNdefMessage() can be called to test if the target has a
+ stored NDEF message, readNdefMessages() and writeNdefMessages() functions can be used to get
+ and set the NDEF message.
+
+ If the target supports TagTypeSpecificAccess, sendCommand() can be used to send a single
+ proprietary command to the target and retrieve the response. sendCommands() can be used to
+ send multiple proprietary commands to the target and retrieve all of the responses.
+
+ If the target supports LlcpAccess, the QLlcpSocket class can be used to connected to a
+ service provided by the target.
+*/
+
+/*!
+ \enum QNearFieldTarget::Type
+
+ This enum describes the type of tag the target is detected as.
+
+ \value AnyTarget This value is only used when registering handlers to indicate that any
+ compatible target can be used.
+ \value ProprietaryTag An unidentified proprietary target tag.
+ \value NfcTagType1 An NFC tag type 1 target.
+ \value NfcTagType2 An NFC tag type 2 target.
+ \value NfcTagType3 An NFC tag type 3 target.
+ \value NfcTagType4 An NFC tag type 4 target.
+ \value MifareTag A Mifare target.
+ \value NfcForumDevice An NFC Forum device target.
+*/
+
+/*!
+ \enum QNearFieldTarget::AccessMethod
+
+ This enum describes the access methods a near field target supports.
+
+ \value NdefAccess The target supports reading and writing NDEF messages using
+ readNdefMessages() and writeNdefMessages().
+ \value TagTypeSpecificAccess The target supports sending tag type specific commands using
+ sendCommand() and sendCommands().
+ \value LlcpAccess The target supports peer-to-peer LLCP communication.
+*/
+
+/*!
+ \enum QNearFieldTarget::Error
+
+ This enum describes the error codes that that a near field target reports.
+
+ \value NoError No error has occurred.
+ \value UnknownError An unidentified error occurred.
+ \value UnsupportedError The requested operation is unsupported by this near field
+ target.
+ \value TargetOutOfRangeError The target is no longer within range.
+ \value NoResponseError The target did not respond.
+ \value ChecksumMismatchError The checksum has detected a corrupted response.
+ \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.
+*/
+
+/*!
+ \fn qNfcChecksum(const char *data, uint len)
+
+ \relates QNearFieldTarget
+
+ Returns the NFC checksum of the first \a len bytes of \a data.
+*/
+#include "checksum_p.h"
+
+/*!
+ \fn void QNearFieldTarget::disconnected()
+
+ This signal is emitted when the near field target moves out of proximity.
+*/
+
+/*!
+ \fn void QNearFieldTarget::ndefMessageRead(const QNdefMessage &message)
+
+ This signal is emitted when a complete NDEF \a message has been read from the target.
+
+ \sa readNdefMessages()
+*/
+
+/*!
+ \fn void QNearFieldTarget::ndefMessagesWritten()
+
+ This signal is emitted when NDEF messages have been successfully written to the target.
+
+ \sa writeNdefMessages()
+*/
+
+/*!
+ \fn void QNearFieldTarget::requestCompleted(const QNearFieldTarget::RequestId &id)
+
+ This signal is emitted when a request \a id completes.
+
+ \sa sendCommand()
+*/
+
+/*!
+ \fn void QNearFieldTarget::error(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id)
+
+ This signal is emitted when an error occurs while processing request \a id. The \a error
+ parameter describes the error.
+*/
+
+/*!
+ Constructs a new invalid request id handle.
+*/
+QNearFieldTarget::RequestId::RequestId()
+{
+}
+
+/*!
+ Constructs a new request id handle that is a copy of \a other.
+*/
+QNearFieldTarget::RequestId::RequestId(const RequestId &other)
+: d(other.d)
+{
+}
+
+/*!
+ \internal
+*/
+QNearFieldTarget::RequestId::RequestId(RequestIdPrivate *p)
+: d(p)
+{
+}
+
+/*!
+ Destroys the request id handle.
+*/
+QNearFieldTarget::RequestId::~RequestId()
+{
+}
+
+/*!
+ Returns true if this is a valid request id; otherwise returns false.
+*/
+bool QNearFieldTarget::RequestId::isValid() const
+{
+ return d;
+}
+
+/*!
+ Returns the current reference count of the request id.
+*/
+int QNearFieldTarget::RequestId::refCount() const
+{
+ if (d)
+ return d->ref;
+
+ return 0;
+}
+
+/*!
+ \internal
+*/
+bool QNearFieldTarget::RequestId::operator<(const RequestId &other) const
+{
+ return d < other.d;
+}
+
+/*!
+ \internal
+*/
+bool QNearFieldTarget::RequestId::operator==(const RequestId &other) const
+{
+ return d == other.d;
+}
+
+/*!
+ \internal
+*/
+bool QNearFieldTarget::RequestId::operator!=(const RequestId &other) const
+{
+ return d != other.d;
+}
+
+/*!
+ Assigns a copy of \a other to this request id and returns a reference to this request id.
+*/
+QNearFieldTarget::RequestId &QNearFieldTarget::RequestId::operator=(const RequestId &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Constructs a new near field target with \a parent.
+*/
+QNearFieldTarget::QNearFieldTarget(QObject *parent)
+: QObject(parent), d_ptr(new QNearFieldTargetPrivate)
+{
+ qRegisterMetaType<RequestId>("QNearFieldTarget::RequestId");
+ qRegisterMetaType<Error>("QNearFieldTarget::Error");
+}
+
+/*!
+ Destroys the near field target.
+*/
+QNearFieldTarget::~QNearFieldTarget()
+{
+ delete d_ptr;
+}
+
+/*!
+ \fn QByteArray QNearFieldTarget::uid() const = 0
+
+ Returns the UID of the near field target.
+*/
+
+/*!
+ Returns the URL of the near field target.
+*/
+QUrl QNearFieldTarget::url() const
+{
+ return QUrl();
+}
+
+/*!
+ \fn QNearFieldTarget::Type QNearFieldTarget::type() const = 0
+
+ Returns the type of tag type of this near field target.
+*/
+
+/*!
+ \fn QNearFieldTarget::AccessMethods QNearFieldTarget::accessMethods() const = 0
+
+ Returns the access methods support by this near field target.
+*/
+
+/*!
+ Returns true if the target is processing commands; otherwise returns false.
+*/
+bool QNearFieldTarget::isProcessingCommand() const
+{
+ return false;
+}
+
+/*!
+ Returns true if at least one NDEF message is stored on the near field target; otherwise returns
+ false.
+*/
+bool QNearFieldTarget::hasNdefMessage()
+{
+ return false;
+}
+
+/*!
+ Starts reading NDEF messages stored on the near field target. Returns a request id which can
+ be used to track the completion status of the request. An invalid request id will be returned
+ if the target does not support reading NDEF messages.
+
+ An ndefMessageRead() signal will be emitted for each NDEF message. The requestCompleted()
+ signal will be emitted was all NDEF messages have been read. The error() signal is emitted if
+ an error occurs.
+
+ \note Symbian^3 and Maemo 6 only support read one NDEF message.
+*/
+QNearFieldTarget::RequestId QNearFieldTarget::readNdefMessages()
+{
+ return RequestId();
+}
+
+/*!
+ Writes the NDEF messages in \a messages to the target. Returns a request id which can be used
+ to track the completion status of the request. An invalid request id will be returned if the
+ target does not support reading NDEF messages.
+
+ The ndefMessagesWritten() signal will be emitted when the write operation completes
+ successfully; otherwise the error() signal is emitted.
+
+ \note Symbian^3 and Maemo 6 only support writing one NDEF message. Only the first NDEF message
+ in the list will be written, others are silently dropped.
+*/
+QNearFieldTarget::RequestId QNearFieldTarget::writeNdefMessages(const QList<QNdefMessage> &messages)
+{
+ Q_UNUSED(messages);
+
+ return RequestId();
+}
+
+/*!
+ Sends \a command to the near field target. Returns a request id which can be used to track the
+ completion status of the request. An invalid request id will be returned if the target does not
+ support sending tag type specific commands.
+
+ The requestCompleted() signal will be emitted on successful completion of the request;
+ otherwise the error() signal will be emitted.
+
+ Once the request completes successfully the response can be retrieved from the
+ requestResponse() function. The response of this request will be a QByteArray.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTarget::sendCommand(const QByteArray &command)
+{
+ Q_UNUSED(command);
+
+ emit error(UnsupportedError, RequestId());
+
+ return RequestId();
+}
+
+/*!
+ Sends multiple \a commands to the near field target. Returns a request id which can be used to
+ track the completion status of the request. An invalid request id will be returned if the
+ target does not support sending tag type specific commands.
+
+ If all commands complete successfully the requestCompleted() signal will be emitted; otherwise
+ the error() signal will be emitted. If a command fails succeeding commands from this call will
+ not be processed.
+
+ Once the request completes the response for successfully completed requests can be retrieved
+ from the requestResponse() function. The response of this request will be a QList<QByteArray>.
+
+ \sa requestCompleted(), waitForRequestCompleted()
+*/
+QNearFieldTarget::RequestId QNearFieldTarget::sendCommands(const QList<QByteArray> &commands)
+{
+ Q_UNUSED(commands);
+
+ emit error(UnsupportedError, RequestId());
+
+ return RequestId();
+}
+
+/*!
+ Waits up to \a msecs milliseconds for the request \a id to complete. Returns true if the
+ request completes successfully and the requestCompeted() signal is emitted; otherwise returns
+ false.
+*/
+bool QNearFieldTarget::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ Q_UNUSED(msecs);
+
+ Q_D(QNearFieldTarget);
+
+ return d->m_decodedResponses.contains(id);
+}
+
+/*!
+ Returns the decoded response for request \a id. If the request is unknown or has not yet been
+ completed an invalid QVariant is returned.
+*/
+QVariant QNearFieldTarget::requestResponse(const RequestId &id)
+{
+ Q_D(QNearFieldTarget);
+
+ return d->m_decodedResponses.value(id);
+}
+
+/*!
+ Sets the decoded response for request \a id to \a response. If \a emitRequestCompleted is true
+ the requestCompleted() signal will be emitted for \a id; otherwise no signal will be emitted.
+
+ \sa requestResponse()
+*/
+void QNearFieldTarget::setResponseForRequest(const QNearFieldTarget::RequestId &id,
+ const QVariant &response, bool emitRequestCompleted)
+{
+ Q_D(QNearFieldTarget);
+
+ QMutableMapIterator<RequestId, QVariant> i(d->m_decodedResponses);
+ while (i.hasNext()) {
+ i.next();
+
+ // no more external references
+ if (i.key().refCount() == 1)
+ i.remove();
+ }
+
+ d->m_decodedResponses.insert(id, response);
+
+ if (emitRequestCompleted)
+ emit requestCompleted(id);
+}
+
+/*!
+ Handles the \a response received for the request \a id. Returns true if the response is
+ handled; otherwise returns false.
+
+ Classes reimplementing this virtual function should call the base class implementation to
+ ensure that requests initiated by those classes are handled correctly.
+
+ The default implementation stores the response such that it can be retrieved by
+ requestResponse().
+*/
+bool QNearFieldTarget::handleResponse(const QNearFieldTarget::RequestId &id,
+ const QByteArray &response)
+{
+ setResponseForRequest(id, response);
+
+ return true;
+}
+
+#include "moc_qnearfieldtarget.cpp"
diff --git a/src/nfc/qnearfieldtarget.h b/src/nfc/qnearfieldtarget.h
new file mode 100644
index 00000000..7e081660
--- /dev/null
+++ b/src/nfc/qnearfieldtarget.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QNEARFIELDTARGET_H
+#define QNEARFIELDTARGET_H
+
+#include "../qtconnectivityglobal.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QMetaType>
+#include <QtCore/QSharedDataPointer>
+
+class QString;
+class QUrl;
+
+QT_BEGIN_HEADER
+
+class QNdefMessage;
+class QNearFieldTargetPrivate;
+
+class Q_CONNECTIVITY_EXPORT QNearFieldTarget : public QObject
+{
+ Q_OBJECT
+
+ Q_DECLARE_PRIVATE(QNearFieldTarget)
+
+public:
+ enum Type {
+ AnyTarget,
+ ProprietaryTag,
+ NfcTagType1,
+ NfcTagType2,
+ NfcTagType3,
+ NfcTagType4,
+ MifareTag,
+ NfcForumDevice
+ };
+
+ enum AccessMethod {
+ NdefAccess,
+ TagTypeSpecificAccess,
+ LlcpAccess
+ };
+ Q_DECLARE_FLAGS(AccessMethods, AccessMethod)
+
+ enum Error {
+ NoError,
+ UnknownError,
+ UnsupportedError,
+ TargetOutOfRangeError,
+ NoResponseError,
+ ChecksumMismatchError,
+ InvalidParametersError,
+ NdefReadError,
+ NdefWriteError
+ };
+
+ class RequestIdPrivate;
+ class Q_CONNECTIVITY_EXPORT RequestId
+ {
+ public:
+ RequestId();
+ RequestId(const RequestId &other);
+ RequestId(RequestIdPrivate *p);
+ ~RequestId();
+
+ bool isValid() const;
+
+ int refCount() const;
+
+ bool operator<(const RequestId &other) const;
+ bool operator==(const RequestId &other) const;
+ bool operator!=(const RequestId &other) const;
+ RequestId &operator=(const RequestId &other);
+
+ QSharedDataPointer<RequestIdPrivate> d;
+ };
+
+ explicit QNearFieldTarget(QObject *parent = 0);
+ virtual ~QNearFieldTarget();
+
+ virtual QByteArray uid() const = 0;
+ virtual QUrl url() const;
+
+ virtual Type type() const = 0;
+ virtual AccessMethods accessMethods() const = 0;
+
+ bool isProcessingCommand() const;
+
+ // NdefAccess
+ virtual bool hasNdefMessage();
+ virtual RequestId readNdefMessages();
+ virtual RequestId writeNdefMessages(const QList<QNdefMessage> &messages);
+
+ // TagTypeSpecificAccess
+ virtual RequestId sendCommand(const QByteArray &command);
+ virtual RequestId sendCommands(const QList<QByteArray> &commands);
+
+ virtual bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+ QVariant requestResponse(const RequestId &id);
+ void setResponseForRequest(const QNearFieldTarget::RequestId &id, const QVariant &response,
+ bool emitRequestCompleted = true);
+
+protected:
+ Q_INVOKABLE virtual bool handleResponse(const QNearFieldTarget::RequestId &id,
+ const QByteArray &response);
+
+Q_SIGNALS:
+ void disconnected();
+
+ void ndefMessageRead(const QNdefMessage &message);
+ void ndefMessagesWritten();
+
+ void requestCompleted(const QNearFieldTarget::RequestId &id);
+
+ void error(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id);
+
+private:
+ QNearFieldTargetPrivate *d_ptr;
+};
+
+Q_CONNECTIVITY_EXPORT quint16 qNfcChecksum(const char * data, uint len);
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QNearFieldTarget::AccessMethods)
+
+Q_DECLARE_METATYPE(QNearFieldTarget::RequestId)
+Q_DECLARE_METATYPE(QNearFieldTarget::Error)
+
+QT_END_HEADER
+
+#endif // QNEARFIELDTARGET_H
diff --git a/src/nfc/qnearfieldtarget_emulator.cpp b/src/nfc/qnearfieldtarget_emulator.cpp
new file mode 100644
index 00000000..2a05a6e3
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_emulator.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtarget_emulator_p.h"
+#include "qnearfieldtarget_p.h"
+
+#include <QtCore/QDirIterator>
+#include <QtCore/QSettings>
+#include <QtCore/QMutex>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDateTime>
+
+#include <QtCore/QDebug>
+
+static QMutex tagMutex;
+static QMap<TagBase *, bool> tagMap;
+static TagActivator tagActivator;
+
+
+TagType1::TagType1(TagBase *tag, QObject *parent)
+: QNearFieldTagType1(parent), m_tag(tag)
+{
+}
+
+TagType1::~TagType1()
+{
+}
+
+QByteArray TagType1::uid() const
+{
+ QMutexLocker locker(&tagMutex);
+
+ return m_tag->uid();
+}
+
+QNearFieldTarget::AccessMethods TagType1::accessMethods() const
+{
+ return NdefAccess | TagTypeSpecificAccess;
+}
+
+QNearFieldTarget::RequestId TagType1::sendCommand(const QByteArray &command)
+{
+ QMutexLocker locker(&tagMutex);
+
+ RequestId id(new RequestIdPrivate);
+
+ // tag not in proximity
+ if (!tagMap.value(m_tag)) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, TargetOutOfRangeError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ quint16 crc = qNfcChecksum(command.constData(), command.length());
+
+ QByteArray response = m_tag->processCommand(command + char(crc & 0xff) + char(crc >> 8));
+
+ if (response.isEmpty()) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, NoResponseError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ // check crc
+ if (qNfcChecksum(response.constData(), response.length()) != 0) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, ChecksumMismatchError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ response.chop(2);
+
+ QMetaObject::invokeMethod(this, "handleResponse", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::RequestId, id), Q_ARG(QByteArray, response));
+
+ return id;
+}
+
+bool TagType1::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ QCoreApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+ return QNearFieldTagType1::waitForRequestCompleted(id, msecs);
+}
+
+
+TagType2::TagType2(TagBase *tag, QObject *parent)
+: QNearFieldTagType2(parent), m_tag(tag)
+{
+}
+
+TagType2::~TagType2()
+{
+}
+
+QByteArray TagType2::uid() const
+{
+ QMutexLocker locker(&tagMutex);
+
+ return m_tag->uid();
+}
+
+QNearFieldTarget::AccessMethods TagType2::accessMethods() const
+{
+ return NdefAccess | TagTypeSpecificAccess;
+}
+
+QNearFieldTarget::RequestId TagType2::sendCommand(const QByteArray &command)
+{
+ QMutexLocker locker(&tagMutex);
+
+ RequestId id(new RequestIdPrivate);
+
+ // tag not in proximity
+ if (!tagMap.value(m_tag)) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, TargetOutOfRangeError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ quint16 crc = qNfcChecksum(command.constData(), command.length());
+
+ QByteArray response = m_tag->processCommand(command + char(crc & 0xff) + char(crc >> 8));
+
+ if (response.isEmpty())
+ return id;
+
+ if (response.length() > 1) {
+ // check crc
+ if (qNfcChecksum(response.constData(), response.length()) != 0) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, ChecksumMismatchError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ return id;
+ }
+
+ response.chop(2);
+ }
+
+ QMetaObject::invokeMethod(this, "handleResponse", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::RequestId, id), Q_ARG(QByteArray, response));
+
+ return id;
+}
+
+bool TagType2::waitForRequestCompleted(const RequestId &id, int msecs)
+{
+ QCoreApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+ return QNearFieldTagType2::waitForRequestCompleted(id, msecs);
+}
+
+
+TagActivator::TagActivator()
+: timerId(-1)
+{
+ qRegisterMetaType<QNearFieldTarget::Error>("QNearFieldTarget::Error");
+}
+
+TagActivator::~TagActivator()
+{
+ QMutexLocker locker(&tagMutex);
+ qDeleteAll(tagMap.keys());
+ tagMap.clear();
+}
+
+void TagActivator::initialize()
+{
+ QMutexLocker locker(&tagMutex);
+
+ if (!tagMap.isEmpty())
+ return;
+
+ QDirIterator nfcTargets(QDir::currentPath(), QStringList(QLatin1String("*.nfc")), QDir::Files);
+ while (nfcTargets.hasNext()) {
+ const QString targetFilename = nfcTargets.next();
+
+ QSettings target(targetFilename, QSettings::IniFormat);
+
+ target.beginGroup(QLatin1String("Target"));
+
+ const QString tagType = target.value(QLatin1String("Type")).toString();
+
+ target.endGroup();
+
+ if (tagType == QLatin1String("TagType1")) {
+ qDebug() << "loading" << targetFilename << "as NfcTagType1";
+ NfcTagType1 *tag = new NfcTagType1;
+ tag->load(&target);
+
+ tagMap.insert(tag, false);
+ } else if (tagType == QLatin1String("TagType2")) {
+ qDebug() << "loading" << targetFilename << "as NfcTagType2";
+ NfcTagType2 *tag = new NfcTagType2;
+ tag->load(&target);
+
+ tagMap.insert(tag, false);
+ } else {
+ qWarning("Unknown tag type %s\n", qPrintable(tagType));
+ }
+ }
+
+ m_current = tagMap.end();
+
+ timerId = startTimer(1000);
+}
+
+void TagActivator::reset()
+{
+ QMutexLocker locker(&tagMutex);
+
+ killTimer(timerId);
+ timerId = -1;
+
+ qDeleteAll(tagMap.keys());
+ tagMap.clear();
+}
+
+TagActivator *TagActivator::instance()
+{
+ return &tagActivator;
+}
+
+void TagActivator::timerEvent(QTimerEvent *e)
+{
+ Q_UNUSED(e);
+
+ tagMutex.lock();
+
+ if (m_current != tagMap.end()) {
+ if (m_current.key()->lastAccessTime() + 1500 > QDateTime::currentMSecsSinceEpoch()) {
+ tagMutex.unlock();
+ return;
+ }
+
+ *m_current = false;
+
+ tagMutex.unlock();
+ emit tagDeactivated(m_current.key());
+ tagMutex.lock();
+ }
+
+ ++m_current;
+ if (m_current == tagMap.end())
+ m_current = tagMap.begin();
+
+ if (m_current != tagMap.end()) {
+ *m_current = true;
+
+ tagMutex.unlock();
+
+ emit tagActivated(m_current.key());
+ tagMutex.lock();
+ }
+
+ tagMutex.unlock();
+}
+
diff --git a/src/nfc/qnearfieldtarget_emulator_p.h b/src/nfc/qnearfieldtarget_emulator_p.h
new file mode 100644
index 00000000..1867df89
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_emulator_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTARGET_EMULATOR_P_H
+#define QNEARFIELDTARGET_EMULATOR_P_H
+
+#include "qnearfieldtagtype1.h"
+#include "qnearfieldtagtype2.h"
+#include "targetemulator_p.h"
+
+#include <QtCore/QMap>
+
+class TagType1 : public QNearFieldTagType1
+{
+ Q_OBJECT
+
+public:
+ TagType1(TagBase *tag, QObject *parent);
+ ~TagType1();
+
+ QByteArray uid() const;
+
+ AccessMethods accessMethods() const;
+
+ RequestId sendCommand(const QByteArray &command);
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+private:
+ TagBase *m_tag;
+};
+
+class TagType2 : public QNearFieldTagType2
+{
+ Q_OBJECT
+
+public:
+ TagType2(TagBase *tag, QObject *parent);
+ ~TagType2();
+
+ QByteArray uid() const;
+
+ AccessMethods accessMethods() const;
+
+ RequestId sendCommand(const QByteArray &command);
+ bool waitForRequestCompleted(const RequestId &id, int msecs = 5000);
+
+private:
+ TagBase *m_tag;
+};
+
+class TagActivator : public QObject
+{
+ Q_OBJECT
+
+public:
+ TagActivator();
+ ~TagActivator();
+
+ void initialize();
+ void reset();
+
+ static TagActivator *instance();
+
+protected:
+ void timerEvent(QTimerEvent *e);
+
+signals:
+ void tagActivated(TagBase *tag);
+ void tagDeactivated(TagBase *tag);
+
+private:
+ QMap<TagBase *, bool>::Iterator m_current;
+ int timerId;
+};
+
+#endif // QNEARFIELDTARGET_EMULATOR_P_H
diff --git a/src/nfc/qnearfieldtarget_maemo6.cpp b/src/nfc/qnearfieldtarget_maemo6.cpp
new file mode 100644
index 00000000..dddf8776d
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_maemo6.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldtarget_maemo6_p.h"
+
+void PendingCallWatcher::addSendCommand(const QDBusPendingReply<QByteArray> &reply,
+ const QNearFieldTarget::RequestId &id)
+{
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(sendCommandFinished(QDBusPendingCallWatcher*)));
+
+ m_pendingCommands.insert(watcher, id);
+}
+
+void PendingCallWatcher::addReadNdefMessages(const QDBusPendingReply<QList<QByteArray> > &reply,
+ const QNearFieldTarget::RequestId &id)
+{
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(readNdefMessagesFinished(QDBusPendingCallWatcher*)));
+
+ m_pendingNdefReads.insert(watcher, id);
+}
+
+void PendingCallWatcher::addWriteNdefMessages(const QDBusPendingReply<> &reply,
+ const QNearFieldTarget::RequestId &id)
+{
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(writeNdefMessages(QDBusPendingCallWatcher*)));
+
+ m_pendingNdefWrites.insert(watcher, id);
+}
+
+void PendingCallWatcher::sendCommandFinished(QDBusPendingCallWatcher *watcher)
+{
+ QNearFieldTarget::RequestId id = m_pendingCommands.take(watcher);
+
+ if (!id.isValid()) {
+ watcher->deleteLater();
+ return;
+ }
+
+ QDBusPendingReply<QByteArray> reply = *watcher;
+ if (reply.isError()) {
+ QMetaObject::invokeMethod(parent(), "error",
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::UnknownError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ } else {
+ const QByteArray data = reply.argumentAt<0>();
+ QMetaObject::invokeMethod(parent(), "handleResponse",
+ Q_ARG(QNearFieldTarget::RequestId, id),
+ Q_ARG(QByteArray, data));
+ }
+
+ watcher->deleteLater();
+}
+
+void PendingCallWatcher::readNdefMessagesFinished(QDBusPendingCallWatcher *watcher)
+{
+ QNearFieldTarget::RequestId id = m_pendingNdefReads.take(watcher);
+
+ if (!id.isValid()) {
+ watcher->deleteLater();
+ return;
+ }
+
+ QDBusPendingReply<QList<QByteArray> > reply = *watcher;
+ if (reply.isError()) {
+ QMetaObject::invokeMethod(parent(), "error",
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::NdefReadError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ } else {
+ const QList<QByteArray> data = reply.argumentAt<0>();
+ foreach (const QByteArray &m, data) {
+ qDebug() << Q_FUNC_INFO << m.toHex();
+ const QNdefMessage message = QNdefMessage::fromByteArray(m);
+
+ qDebug() << "record count:" << message.count();
+ foreach (const QNdefRecord &record, message)
+ qDebug() << record.typeNameFormat() << record.type() << record.payload().toHex();
+
+ QMetaObject::invokeMethod(parent(), "ndefMessageRead", Q_ARG(QNdefMessage, message));
+ }
+
+ QMetaObject::invokeMethod(parent(), "requestCompleted",
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ }
+
+ watcher->deleteLater();
+}
+
+void PendingCallWatcher::writeNdefMessages(QDBusPendingCallWatcher *watcher)
+{
+ QNearFieldTarget::RequestId id = m_pendingNdefWrites.take(watcher);
+
+ if (!id.isValid()) {
+ watcher->deleteLater();
+ return;
+ }
+
+ QDBusPendingReply<> reply = *watcher;
+ if (reply.isError()) {
+ QMetaObject::invokeMethod(parent(), "error",
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::NdefWriteError),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ } else {
+ QMetaObject::invokeMethod(parent(), "ndefMessagesWritten");
+ QMetaObject::invokeMethod(parent(), "requestCompleted",
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ }
+
+ watcher->deleteLater();
+}
+
+int TagType1::memorySize() const
+{
+ return m_tag->size();
+}
+
+int TagType2::memorySize() const
+{
+ return m_tag->size();
+}
+
+int TagType3::memorySize() const
+{
+ return m_tag->size();
+}
+
+int TagType4::memorySize() const
+{
+ return m_tag->size();
+}
+
+#include <moc_qnearfieldtarget_maemo6_p.cpp>
+
diff --git a/src/nfc/qnearfieldtarget_maemo6_p.h b/src/nfc/qnearfieldtarget_maemo6_p.h
new file mode 100644
index 00000000..5002a08e
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_maemo6_p.h
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTARGET_MAEMO6_P_H
+#define QNEARFIELDTARGET_MAEMO6_P_H
+
+#include <qconnectivityglobal.h>
+
+#include "qnearfieldmanager_maemo6_p.h"
+
+#include <qnearfieldtarget.h>
+#include <qnearfieldtarget_p.h>
+#include <qnearfieldtagtype1.h>
+#include <qnearfieldtagtype2.h>
+#include <qnearfieldtagtype3.h>
+#include <qnearfieldtagtype4.h>
+#include <qndefmessage.h>
+
+#include "maemo6/adapter_interface_p.h"
+#include "maemo6/target_interface_p.h"
+#include "maemo6/tag_interface_p.h"
+#include "maemo6/device_interface_p.h"
+
+#include <QtDBus/QDBusPendingReply>
+
+using namespace com::nokia::nfc;
+
+class PendingCallWatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ PendingCallWatcher(QObject *parent) : QObject(parent) { }
+
+ void addSendCommand(const QDBusPendingReply<QByteArray> &reply,
+ const QNearFieldTarget::RequestId &id);
+ void addReadNdefMessages(const QDBusPendingReply<QList<QByteArray> > &reply,
+ const QNearFieldTarget::RequestId &id);
+ void addWriteNdefMessages(const QDBusPendingReply<> &reply,
+ const QNearFieldTarget::RequestId &id);
+
+private slots:
+ void sendCommandFinished(QDBusPendingCallWatcher *watcher);
+ void readNdefMessagesFinished(QDBusPendingCallWatcher *watcher);
+ void writeNdefMessages(QDBusPendingCallWatcher *watcher);
+
+private:
+ QMap<QDBusPendingCallWatcher *, QNearFieldTarget::RequestId> m_pendingCommands;
+ QMap<QDBusPendingCallWatcher *, QNearFieldTarget::RequestId> m_pendingNdefReads;
+ QMap<QDBusPendingCallWatcher *, QNearFieldTarget::RequestId> m_pendingNdefWrites;
+};
+
+template <typename T>
+class NearFieldTarget : public T
+{
+public:
+ NearFieldTarget(QNearFieldManagerPrivateImpl *manager, Target *target, Tag *tag)
+ : T(manager), m_manager(manager), m_target(target), m_tag(tag), m_device(0),
+ m_callWatcher(new PendingCallWatcher(this))
+ {
+ }
+
+ NearFieldTarget(QNearFieldManagerPrivateImpl *manager, Target *target, Device *device)
+ : T(manager), m_manager(manager), m_target(target), m_tag(0), m_device(device),
+ m_callWatcher(new PendingCallWatcher(this))
+ {
+ }
+
+ ~NearFieldTarget()
+ {
+ delete m_device;
+ delete m_tag;
+ delete m_target;
+ }
+
+ QByteArray uid() const
+ {
+ QStringList fields;
+
+ if (m_tag)
+ fields = m_tag->uID().split(QLatin1Char(':'));
+ else if (m_device)
+ fields = m_device->uID().split(QLatin1Char(':'));
+
+ QByteArray id;
+ foreach (const QString &f, fields)
+ id.append(char(f.toUInt(0, 16)));
+
+ return id;
+ }
+
+ QNearFieldTarget::Type type() const
+ {
+ if (m_device)
+ return QNearFieldTarget::NfcForumDevice;
+
+ if (m_tag) {
+ const QString tagType = m_tag->technology();
+ if (tagType == QLatin1String("jewel"))
+ return QNearFieldTarget::NfcTagType1;
+ else if (tagType == QLatin1String("mifare-ul"))
+ return QNearFieldTarget::NfcTagType2;
+ else if (tagType == QLatin1String("felica"))
+ return QNearFieldTarget::NfcTagType3;
+ else if (tagType == QLatin1String("iso-4a"))
+ return QNearFieldTarget::NfcTagType4;
+ else if (tagType == QLatin1String("mifare-1k"))
+ return QNearFieldTarget::MifareTag;
+ else
+ return QNearFieldTarget::ProprietaryTag;
+ }
+
+ return QNearFieldTarget::ProprietaryTag;
+ }
+
+ QNearFieldTarget::AccessMethods accessMethods() const
+ {
+ QNearFieldTarget::AccessMethods result = QNearFieldTarget::NdefAccess;
+#ifdef MAEMO6_TAG_TYPE_SEPECIFIC_ACCESS_SUPPORTED
+ if (m_tag)
+ result |= QNearFieldTarget::TagTypeSpecificAccess;
+#endif
+ if (!m_tag)
+ result |= QNearFieldTarget::LlcpAccess;
+
+ return result;
+ }
+
+ bool hasNdefMessage()
+ {
+ return true;
+ }
+
+ QNearFieldTarget::RequestId readNdefMessages()
+ {
+ if (!m_tag)
+ return QNearFieldTarget::RequestId();
+
+ QNearFieldTarget::RequestId id(new QNearFieldTarget::RequestIdPrivate);
+
+ QDBusPendingReply<QList<QByteArray> > reply = m_tag->ReadNDEFData();
+ m_callWatcher->addReadNdefMessages(reply, id);
+
+ return id;
+ }
+
+ QNearFieldTarget::RequestId writeNdefMessages(const QList<QNdefMessage> &messages)
+ {
+ if (!m_tag)
+ return QNearFieldTarget::RequestId();
+
+ QNearFieldTarget::RequestId id(new QNearFieldTarget::RequestIdPrivate);
+ QList<QByteArray> rawMessages;
+
+ foreach (const QNdefMessage &message, messages)
+ rawMessages.append(message.toByteArray());
+
+ QDBusPendingReply<> reply = m_tag->WriteNDEFData(rawMessages);
+ m_callWatcher->addWriteNdefMessages(reply, id);
+
+ return id;
+ }
+
+ QNearFieldTarget::RequestId sendCommand(const QByteArray &command)
+ {
+#if 0
+ quint16 crc = qNfcChecksum(command.constData(), command.length());
+
+ QNearFieldTarget::RequestId id(new QNearFieldTarget::RequestIdPrivate);
+
+ QDBusPendingReply<QByteArray> reply =
+ m_tag->RawRequest(command + char(crc & 0xff) + char(crc >> 8));
+
+ m_callWatcher->addSendCommand(reply, id);
+
+ return id;
+#else
+ Q_UNUSED(command);
+ return QNearFieldTarget::RequestId();
+#endif
+ }
+
+ QNearFieldTarget::RequestId sendCommands(const QList<QByteArray> &commands)
+ {
+#if 0
+ for (int i = 0; i < commandCount; ++i) {
+ reply[i] = m_tag->RawRequest(commands.at(i));
+ }
+
+ QList<QByteArray> results;
+ for (int i = 0; i < commandCount; ++i) {
+ reply[i].waitForFinished();
+ results.append(reply[i].isError() ? QByteArray() : reply->value());
+ }
+
+ return results;
+#else
+ Q_UNUSED(commands);
+ return QNearFieldTarget::RequestId();
+#endif
+ }
+
+protected:
+ QNearFieldManagerPrivateImpl *m_manager;
+ Target *m_target;
+ Tag *m_tag;
+ Device *m_device;
+ PendingCallWatcher *m_callWatcher;
+};
+
+class TagType1 : public NearFieldTarget<QNearFieldTagType1>
+{
+public:
+ TagType1(QNearFieldManagerPrivateImpl *manager, Target *target, Tag *tag)
+ : NearFieldTarget<QNearFieldTagType1>(manager, target, tag)
+ {
+ }
+
+ ~TagType1()
+ {
+ }
+
+ int memorySize() const;
+};
+
+class TagType2 : public NearFieldTarget<QNearFieldTagType2>
+{
+public:
+ TagType2(QNearFieldManagerPrivateImpl *manager, Target *target, Tag *tag)
+ : NearFieldTarget<QNearFieldTagType2>(manager, target, tag)
+ {
+ }
+
+ ~TagType2()
+ {
+ }
+
+ int memorySize() const;
+};
+
+class TagType3 : public NearFieldTarget<QNearFieldTagType3>
+{
+public:
+ TagType3(QNearFieldManagerPrivateImpl *manager, Target *target, Tag *tag)
+ : NearFieldTarget<QNearFieldTagType3>(manager, target, tag)
+ {
+ }
+
+ ~TagType3()
+ {
+ }
+
+ int memorySize() const;
+};
+
+class TagType4 : public NearFieldTarget<QNearFieldTagType4>
+{
+public:
+ TagType4(QNearFieldManagerPrivateImpl *manager, Target *target, Tag *tag)
+ : NearFieldTarget<QNearFieldTagType4>(manager, target, tag)
+ {
+ }
+
+ ~TagType4()
+ {
+ }
+
+ int memorySize() const;
+};
+
+#endif // QNEARFIELDTARGET_MAEMO6_P_H
diff --git a/src/nfc/qnearfieldtarget_p.h b/src/nfc/qnearfieldtarget_p.h
new file mode 100644
index 00000000..d3d98c9b
--- /dev/null
+++ b/src/nfc/qnearfieldtarget_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTARGET_P_H
+#define QNEARFIELDTARGET_P_H
+
+#include "../qtconnectivityglobal.h"
+
+#include "qnearfieldtarget.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QSharedData>
+
+class QNearFieldTarget::RequestIdPrivate : public QSharedData
+{
+};
+
+class QNearFieldTargetPrivate
+{
+public:
+ QMap<QNearFieldTarget::RequestId, QVariant> m_decodedResponses;
+};
+
+#endif // QNEARFIELDTARGET_P_H
diff --git a/src/nfc/qtlv.cpp b/src/nfc/qtlv.cpp
new file mode 100644
index 00000000..83c5d585
--- /dev/null
+++ b/src/nfc/qtlv.cpp
@@ -0,0 +1,528 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtlv_p.h"
+
+#include "qnearfieldtagtype1.h"
+
+#include <QtCore/QVariant>
+
+#include <QtCore/QDebug>
+
+QPair<int, int> qParseReservedMemoryControlTlv(const QByteArray &tlvData)
+{
+ quint8 position = tlvData.at(0);
+ int pageAddr = position >> 4;
+ int byteOffset = position & 0x0f;
+
+ int size = quint8(tlvData.at(1));
+ if (size == 0)
+ size = 256;
+
+ quint8 pageControl = tlvData.at(2);
+ int bytesPerPage = pageControl & 0x0f;
+
+ if (!bytesPerPage)
+ return qMakePair(0, 0);
+
+ int byteAddress = pageAddr * (1 << bytesPerPage) + byteOffset;
+ return qMakePair(byteAddress, size);
+}
+
+QPair<int, int> qParseLockControlTlv(const QByteArray &tlvData)
+{
+ quint8 position = tlvData.at(0);
+ int pageAddr = position >> 4;
+ int byteOffset = position & 0x0f;
+
+ int size = quint8(tlvData.at(1));
+ if (size == 0)
+ size = 256;
+ size = size / 8;
+
+ quint8 pageControl = tlvData.at(2);
+ int bytesPerPage = pageControl & 0x0f;
+
+ if (!bytesPerPage)
+ return qMakePair(0, 0);
+
+ int byteAddress = pageAddr * (1 << bytesPerPage) + byteOffset;
+ return qMakePair(byteAddress, size);
+}
+
+QTlvReader::QTlvReader(QNearFieldTarget *target)
+: m_target(target), m_index(-1)
+{
+ if (qobject_cast<QNearFieldTagType1 *>(m_target)) {
+ addReservedMemory(0, 12); // skip uid, cc
+ addReservedMemory(104, 16); // skip reserved block D, lock block E
+
+ addReservedMemory(120, 8); // skip reserved block F
+ }
+}
+
+QTlvReader::QTlvReader(const QByteArray &data)
+: m_target(0), m_rawData(data), m_index(-1)
+{
+}
+
+void QTlvReader::addReservedMemory(int offset, int length)
+{
+ m_reservedMemory.insert(offset, length);
+}
+
+/*!
+ Returns the number of bytes of reserved memory found so far. The actual number of reserved
+ bytes will not be known until atEnd() returns true.
+*/
+int QTlvReader::reservedMemorySize() const
+{
+ int total = 0;
+
+ QMap<int, int>::ConstIterator i;
+ for (i = m_reservedMemory.constBegin(); i != m_reservedMemory.constEnd(); ++i)
+ total += i.value();
+
+ return total;
+}
+
+/*!
+ Returns the request id that the TLV reader is currently waiting on.
+*/
+QNearFieldTarget::RequestId QTlvReader::requestId() const
+{
+ return m_requestId;
+}
+
+bool QTlvReader::atEnd() const
+{
+ if (m_index == -1)
+ return false;
+
+ if (m_requestId.isValid())
+ return false;
+
+ return (m_index == m_tlvData.length()) || (tag() == 0xfe);
+}
+
+/*!
+ Moves to the next TLV. Returns true on success; otherwise returns false.
+*/
+bool QTlvReader::readNext()
+{
+ if (atEnd())
+ return false;
+
+ // Move to next TLV
+ if (m_index == -1) {
+ m_index = 0;
+ } else if (m_requestId.isValid()) {
+ // do nothing
+ } else if (tag() == 0x00 || tag() == 0xfe) {
+ ++m_index;
+ } else {
+ int tlvLength = length();
+ m_index += (tlvLength < 0xff) ? tlvLength + 2 : tlvLength + 4;
+ }
+
+ // Ensure that tag byte is available
+ if (!readMoreData(m_index))
+ return false;
+
+ // Ensure that length byte(s) are available
+ if (length() == -1)
+ return false;
+
+ // Ensure that data bytes are available
+ int tlvLength = length();
+
+ int dataOffset = (tlvLength < 0xff) ? m_index + 2 : m_index + 4;
+
+ if (!readMoreData(dataOffset + tlvLength - 1))
+ return false;
+
+ switch (tag()) {
+ case 0x01: { // Lock Control TLV
+ QPair<int, int> locked = qParseLockControlTlv(data());
+ addReservedMemory(locked.first, locked.second);
+ break;
+ }
+ case 0x02: { // Reserved Memory Control TLV
+ QPair<int, int> reserved = qParseReservedMemoryControlTlv(data());
+ addReservedMemory(reserved.first, reserved.second);
+ break;
+ }
+ }
+
+ return true;
+}
+
+quint8 QTlvReader::tag() const
+{
+ return m_tlvData.at(m_index);
+}
+
+int QTlvReader::length()
+{
+ if (tag() == 0x00 || tag() == 0xfe)
+ return 0;
+
+ if (!readMoreData(m_index + 1))
+ return -1;
+
+ quint8 shortLength = m_tlvData.at(m_index + 1);
+ if (shortLength != 0xff)
+ return shortLength;
+
+ if (!readMoreData(m_index + 3))
+ return -1;
+
+ quint16 longLength = (quint8(m_tlvData.at(m_index + 2)) << 8) |
+ quint8(m_tlvData.at(m_index + 3));
+
+ if (longLength < 0xff || longLength == 0xffff) {
+ qWarning("Invalid 3 byte length");
+ return 0;
+ }
+
+ return longLength;
+}
+
+QByteArray QTlvReader::data()
+{
+ int tlvLength = length();
+
+ int dataOffset = (tlvLength < 0xff) ? m_index + 2 : m_index + 4;
+
+ if (!readMoreData(dataOffset + tlvLength - 1))
+ return QByteArray();
+
+ return m_tlvData.mid(dataOffset, tlvLength);
+}
+
+bool QTlvReader::readMoreData(int sparseOffset)
+{
+ while (sparseOffset >= m_tlvData.length()) {
+ int absOffset = absoluteOffset(m_tlvData.length());
+
+ QByteArray data;
+
+ if (!m_rawData.isEmpty()) {
+ data = m_rawData.mid(absOffset, dataLength(absOffset));
+ } else if (QNearFieldTagType1 *tag = qobject_cast<QNearFieldTagType1 *>(m_target)) {
+ quint8 segment = absOffset / 128;
+
+ if (m_requestId.isValid()) {
+ QVariant v = m_target->requestResponse(m_requestId);
+ if (!v.isValid())
+ return false;
+
+ m_requestId = QNearFieldTarget::RequestId();
+
+ data = v.toByteArray();
+
+ if (absOffset < 120)
+ data = data.mid(2);
+
+ int length = dataLength(absOffset);
+
+ data = data.mid(absOffset - (segment * 128), length);
+ } else {
+ m_requestId = (absOffset < 120) ? tag->readAll() : tag->readSegment(segment);
+
+ return false;
+ }
+ }
+
+ if (data.isEmpty() && sparseOffset >= m_tlvData.length())
+ return false;
+
+ m_tlvData.append(data);
+ }
+
+ return true;
+}
+
+int QTlvReader::absoluteOffset(int sparseOffset) const
+{
+ int absoluteOffset = sparseOffset;
+ foreach (int offset, m_reservedMemory.keys()) {
+ if (offset <= absoluteOffset)
+ absoluteOffset += m_reservedMemory.value(offset);
+ }
+
+ return absoluteOffset;
+}
+
+/*!
+ Returns the length of the contiguous non-reserved data block starting from absolute offset
+ \a startOffset. -1 is return as the length of the last contiguous data block.
+*/
+int QTlvReader::dataLength(int startOffset) const
+{
+ foreach (int offset, m_reservedMemory.keys()) {
+ if (offset <= startOffset)
+ continue;
+
+ return offset - startOffset;
+ }
+
+ return -1;
+}
+
+
+QTlvWriter::QTlvWriter(QNearFieldTarget *target)
+: m_target(target), m_rawData(0), m_index(0), m_tagMemorySize(-1)
+{
+ if (qobject_cast<QNearFieldTagType1 *>(m_target)) {
+ addReservedMemory(0, 12); // skip uid, cc
+ addReservedMemory(104, 16); // skip reserved block D, lock block E
+
+ addReservedMemory(120, 8); // skip reserved block F
+ }
+}
+
+QTlvWriter::QTlvWriter(QByteArray *data)
+: m_target(0), m_rawData(data), m_index(0), m_tagMemorySize(-1)
+{
+}
+
+QTlvWriter::~QTlvWriter()
+{
+ if (m_rawData)
+ process(true);
+}
+
+void QTlvWriter::addReservedMemory(int offset, int length)
+{
+ m_reservedMemory.insert(offset, length);
+}
+
+void QTlvWriter::writeTlv(quint8 tagType, const QByteArray &data)
+{
+ m_buffer.append(tagType);
+
+ if (tagType != 0x00 && tagType != 0xfe) {
+ int length = data.length();
+ if (length < 0xff) {
+ m_buffer.append(quint8(length));
+ } else {
+ m_buffer.append(0xff);
+ m_buffer.append(quint16(length) >> 8);
+ m_buffer.append(quint16(length) & 0x00ff);
+ }
+
+ m_buffer.append(data);
+ }
+
+ process();
+
+ switch (tagType) {
+ case 0x01: { // Lock Control TLV
+ QPair<int, int> locked = qParseLockControlTlv(data);
+ addReservedMemory(locked.first, locked.second);
+ break;
+ }
+ case 0x02: { // Reserved Memory Control TLV
+ QPair<int, int> reserved = qParseReservedMemoryControlTlv(data);
+ addReservedMemory(reserved.first, reserved.second);
+ break;
+ }
+ }
+}
+
+/*!
+ Processes more of the TLV writer process. Returns true if the TLVs have been successfully
+ written to the target or buffer; otherwise returns false.
+
+ A false return value indicates that an NFC request is pending (if requestId() returns a valid
+ request identifier) or the write process has failed (requestId() returns an invalid request
+ identifier).
+*/
+bool QTlvWriter::process(bool all)
+{
+ if (m_requestId.isValid()) {
+ QVariant v = m_target->requestResponse(m_requestId);
+ if (!v.isValid())
+ return false;
+ }
+
+ if (m_tagMemorySize == -1) {
+ if (m_rawData)
+ m_tagMemorySize = m_rawData->length();
+ else if (QNearFieldTagType1 *tag = qobject_cast<QNearFieldTagType1 *>(m_target)) {
+ if (m_requestId.isValid()) {
+ m_tagMemorySize = 8 * (tag->requestResponse(m_requestId).toUInt() + 1);
+ m_requestId = QNearFieldTarget::RequestId();
+ } else {
+ m_requestId = tag->readByte(10);
+ return false;
+ }
+ }
+ }
+
+ while (!m_buffer.isEmpty()) {
+ int spaceRemaining = moveToNextAvailable();
+ if (spaceRemaining < 1)
+ return false;
+
+ int length = qMin(spaceRemaining, m_buffer.length());
+
+ if (m_rawData) {
+ m_rawData->replace(m_index, length, m_buffer);
+ m_index += length;
+ m_buffer = m_buffer.mid(length);
+ } else if (QNearFieldTagType1 *tag = qobject_cast<QNearFieldTagType1 *>(m_target)) {
+ int bufferIndex = 0;
+
+ // static memory - can only use writeByte()
+ while (m_index < 120 && bufferIndex < length) {
+ if (m_requestId.isValid()) {
+ if (!m_target->requestResponse(m_requestId).toBool())
+ return false;
+
+ m_requestId = QNearFieldTarget::RequestId();
+
+ ++m_index;
+ ++bufferIndex;
+ } else {
+ m_requestId = tag->writeByte(m_index, m_buffer.at(bufferIndex));
+ m_buffer = m_buffer.mid(bufferIndex);
+ return false;
+ }
+ }
+
+
+ // dynamic memory - writeBlock() full
+ while (m_index >= 120 && (m_index % 8 == 0) && bufferIndex + 8 < length) {
+ if (m_requestId.isValid()) {
+ if (!m_target->requestResponse(m_requestId).toBool())
+ return false;
+
+ m_requestId = QNearFieldTarget::RequestId();
+
+ m_index += 8;
+ bufferIndex += 8;
+ } else {
+ m_requestId = tag->writeBlock(m_index / 8, m_buffer.mid(bufferIndex, 8));
+ m_buffer = m_buffer.mid(bufferIndex);
+ return false;
+ }
+ }
+
+ // partial block
+ int currentBlock = m_index / 8;
+ int nextBlock = currentBlock + 1;
+ int currentBlockStart = currentBlock * 8;
+ int nextBlockStart = nextBlock * 8;
+
+ int fillLength = qMin(nextBlockStart - m_index, spaceRemaining - bufferIndex);
+
+ if (fillLength && (all || m_buffer.length() - bufferIndex >= fillLength) &&
+ (m_buffer.length() != bufferIndex)) {
+ // sufficient data available
+ if (m_requestId.isValid()) {
+ const QVariant v = tag->requestResponse(m_requestId);
+ if (v.type() == QVariant::ByteArray) {
+ // read in block
+ QByteArray block = v.toByteArray();
+
+ int fill = qMin(fillLength, m_buffer.length() - bufferIndex);
+
+ for (int i = m_index - currentBlockStart; i < fill; ++i)
+ block[i] = m_buffer.at(bufferIndex++);
+
+ // now write block
+ m_requestId = tag->writeBlock(currentBlock, block);
+ return false;
+ } else if (v.type() == QVariant::Bool) {
+ m_requestId = QNearFieldTarget::RequestId();
+ int fill = qMin(fillLength, m_buffer.length() - bufferIndex);
+ bufferIndex = fill - (m_index - currentBlockStart);
+
+ // write complete
+ if (!v.toBool())
+ return false;
+ }
+ } else {
+ // read in block
+ m_requestId = tag->readBlock(currentBlock);
+ m_buffer = m_buffer.mid(bufferIndex);
+ return false;
+ }
+ }
+
+ m_buffer = m_buffer.mid(bufferIndex);
+ }
+ }
+
+ return true;
+}
+
+QNearFieldTarget::RequestId QTlvWriter::requestId() const
+{
+ return m_requestId;
+}
+
+int QTlvWriter::moveToNextAvailable()
+{
+ int length = -1;
+
+ // move index to next available byte
+ QMap<int, int>::ConstIterator i;
+ for (i = m_reservedMemory.constBegin(); i != m_reservedMemory.constEnd(); ++i) {
+ if (m_index < i.key()) {
+ length = i.key() - m_index;
+ break;
+ } else if (m_index == i.key()) {
+ m_index += i.value();
+ } else if (m_index > i.key() && m_index < (i.key() + i.value())) {
+ m_index = i.key() + i.value();
+ }
+ }
+
+ if (length == -1)
+ return m_tagMemorySize - m_index;
+
+ Q_ASSERT(length != -1);
+
+ return length;
+}
diff --git a/src/nfc/qtlv_p.h b/src/nfc/qtlv_p.h
new file mode 100644
index 00000000..a47d1a93
--- /dev/null
+++ b/src/nfc/qtlv_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTLV_P_H
+#define QTLV_P_H
+
+#include "../qtconnectivityglobal.h"
+
+#include "qnearfieldtarget.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QMap>
+#include <QtCore/QPair>
+
+QT_BEGIN_HEADER
+
+class QNearFieldTarget;
+class QM_AUTOTEST_EXPORT QTlvReader
+{
+public:
+ explicit QTlvReader(QNearFieldTarget *target);
+ explicit QTlvReader(const QByteArray &data);
+
+ void addReservedMemory(int offset, int length);
+ int reservedMemorySize() const;
+
+ QNearFieldTarget::RequestId requestId() const;
+
+ bool atEnd() const;
+
+ bool readNext();
+
+ quint8 tag() const;
+ int length();
+ QByteArray data();
+
+private:
+ bool readMoreData(int sparseOffset);
+ int absoluteOffset(int sparseOffset) const;
+ int dataLength(int startOffset) const;
+
+ QNearFieldTarget *m_target;
+ QByteArray m_rawData;
+ QNearFieldTarget::RequestId m_requestId;
+
+ QByteArray m_tlvData;
+ int m_index;
+ QMap<int, int> m_reservedMemory;
+};
+
+class QTlvWriter
+{
+public:
+ explicit QTlvWriter(QNearFieldTarget *target);
+ explicit QTlvWriter(QByteArray *data);
+ ~QTlvWriter();
+
+ void addReservedMemory(int offset, int length);
+
+ void writeTlv(quint8 tag, const QByteArray &data = QByteArray());
+
+ bool process(bool all = false);
+
+ QNearFieldTarget::RequestId requestId() const;
+
+private:
+ int moveToNextAvailable();
+
+ QNearFieldTarget *m_target;
+ QByteArray *m_rawData;
+
+ int m_index;
+ int m_tagMemorySize;
+ QMap<int, int> m_reservedMemory;
+
+ QByteArray m_buffer;
+
+ QNearFieldTarget::RequestId m_requestId;
+};
+
+QPair<int, int> qParseReservedMemoryControlTlv(const QByteArray &tlvData);
+QPair<int, int> qParseLockControlTlv(const QByteArray &tlvData);
+
+QT_END_HEADER
+
+#endif // QTLV_P_H
diff --git a/src/nfc/qtnfcversion.h b/src/nfc/qtnfcversion.h
new file mode 100644
index 00000000..e182a3f9
--- /dev/null
+++ b/src/nfc/qtnfcversion.h
@@ -0,0 +1,9 @@
+/* This file was generated by syncqt with the info from sync.profile. */
+#ifndef QT_QTNFC_VERSION_H
+#define QT_QTNFC_VERSION_H
+
+#define QTNFC_VERSION_STR "5.0.0"
+
+#define QTNFC_VERSION 0x050000
+
+#endif // QT_QTNFC_VERSION_H
diff --git a/src/nfc/symbian/debug.h b/src/nfc/symbian/debug.h
new file mode 100644
index 00000000..06a4de9b
--- /dev/null
+++ b/src/nfc/symbian/debug.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEBUG_H_
+#define DEBUG_H_
+#include <QDebug>
+
+//#define SYMBIAN_NFC_DEBUG
+
+#ifdef SYMBIAN_NFC_DEBUG
+# define BEGIN qDebug()<<__PRETTY_FUNCTION__<<" Line: "<<__LINE__ <<" Begin";
+# define END qDebug()<<__PRETTY_FUNCTION__<<" Line: "<<__LINE__ <<" End";
+# define BEGIN_END qDebug()<<__PRETTY_FUNCTION__<<" Line: "<<__LINE__ <<" BEGIN_End";
+# define LOG(a) qDebug()<<__PRETTY_FUNCTION__<<" Line: "<<__LINE__ <<a;
+#else
+# define BEGIN
+# define END
+# define BEGIN_END
+# define LOG(a)
+#endif
+
+#endif /* DEBUG_H_ */
diff --git a/src/nfc/symbian/llcpserver_symbian.cpp b/src/nfc/symbian/llcpserver_symbian.cpp
new file mode 100644
index 00000000..26f97874
--- /dev/null
+++ b/src/nfc/symbian/llcpserver_symbian.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "llcpserver_symbian.h"
+#include "llcpsockettype2_symbian.h"
+#include "../qllcpserver_symbian_p.h"
+#include "nearfieldutility_symbian.h"
+
+#include "debug.h"
+
+/*
+ CLlcpServer::NewL()
+*/
+CLlcpServer* CLlcpServer::NewL(QLlcpServerPrivate& aCallback)
+ {
+ BEGIN
+ CLlcpServer* self = new (ELeave) CLlcpServer(aCallback);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ END
+ return self;
+ }
+
+/*
+ CLlcpServer::CLlcpServer()
+*/
+CLlcpServer::CLlcpServer(QLlcpServerPrivate& aCallback)
+ :iLlcp( NULL ),
+ iSocketListening(EFalse),
+ iCallback(aCallback)
+ {
+ }
+
+/*
+ CLlcpServer::ContructL()
+*/
+void CLlcpServer::ConstructL()
+ {
+ BEGIN
+ User::LeaveIfError(iNfcServer.Open());
+ iLlcp = CLlcpProvider::NewL( iNfcServer );
+ END
+ }
+
+/*
+ Destroys the LLCP socket.
+*/
+CLlcpServer::~CLlcpServer()
+ {
+ BEGIN
+ StopListening();
+ iLlcpSocketArray.ResetAndDestroy();//this should destroy before iLlcp
+ iLlcpSocketArray.Close();
+ iServiceName.Close();
+
+ delete iLlcp;
+ iNfcServer.Close();
+ END
+ }
+
+/*
+ Returns the next pending connection as a connected CLlcpSocketType2
+ object.
+
+ The socket is created as a child of the server, which means that
+ it is automatically deleted when the CLlcpServer object is
+ destroyed. It is still a good idea to delete the object
+ explicitly when you are done with it, to avoid wasting memory.
+*/
+CLlcpSocketType2* CLlcpServer::nextPendingConnection()
+ {
+ // take first element
+ BEGIN
+ CLlcpSocketType2 *llcpSocket = NULL;
+ if (iLlcpSocketArray.Count() > 0)
+ {
+ llcpSocket = iLlcpSocketArray[0];
+ iLlcpSocketArray.Remove(0);
+ }
+ END
+ return llcpSocket;
+ }
+
+TBool CLlcpServer::hasPendingConnections() const
+ {
+ BEGIN
+ END
+ return iLlcpSocketArray.Count() > 0 ? ETrue: EFalse;
+ }
+
+const TDesC8& CLlcpServer::serviceUri() const
+ {
+ BEGIN
+ END
+ return iServiceName;
+ }
+
+/*
+ Listen to the LLCP Socket by the URI \a serviceUri .
+*/
+TBool CLlcpServer::Listen( const TDesC8& aServiceName)
+ {
+ BEGIN
+ TInt error = KErrNone;
+
+ iServiceName.Zero();
+ if (iServiceName.Create(aServiceName.Size()) < 0)
+ {
+ END
+ return EFalse;
+ }
+ iServiceName.Append(aServiceName);
+
+ TRAP(error,iLlcp->StartListeningConnOrientedRequestL( *this, iServiceName ));
+
+ error == KErrNone ? iSocketListening = ETrue : iSocketListening = EFalse;
+ END
+ return iSocketListening;
+ }
+
+void CLlcpServer::StopListening( )
+ {
+ BEGIN
+ if (iSocketListening)
+ {
+ iLlcp->StopListeningConnOrientedRequest( iServiceName );
+ iSocketListening = EFalse;
+ iLlcpSocketArray.ResetAndDestroy();
+ }
+ END
+ }
+
+
+TBool CLlcpServer::isListening() const
+ {
+ BEGIN
+ END
+ return iSocketListening;
+ }
+
+/*
+ Call back from MLlcpConnOrientedListener
+*/
+void CLlcpServer::RemoteConnectRequest( MLlcpConnOrientedTransporter* aConnection )
+ {
+ BEGIN
+ if (aConnection == NULL)
+ {
+ END
+ return;
+ }
+
+ TInt error = KErrNone;
+
+ // create remote connection for the iLlcpsocket
+ aConnection->AcceptConnectRequest();
+
+ CLlcpSocketType2 *llcpSocket = NULL;
+ TRAP(error,llcpSocket = CLlcpSocketType2::NewL(aConnection));
+ // Creating wrapper for connection.
+ if (KErrNone == error)
+ {
+ iLlcpSocketArray.Append(llcpSocket);
+ //The newConnection() signal is then emitted each time a client connects to the server.
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error, iCallback.invokeNewConnection());
+ Q_UNUSED(error);//just skip the error
+ }
+ END
+ }
+//EOF
diff --git a/src/nfc/symbian/llcpserver_symbian.h b/src/nfc/symbian/llcpserver_symbian.h
new file mode 100644
index 00000000..10e0771f
--- /dev/null
+++ b/src/nfc/symbian/llcpserver_symbian.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LLCPSERVER_SYMBIAN_H_
+#define LLCPSERVER_SYMBIAN_H_
+
+#include <e32base.h>
+#include <nfcserver.h> // RNfcServer
+#include <llcpprovider.h> // CLlcpProvider
+#include <llcpconnorientedlistener.h> // MLlcpConnOrientedListener
+#include <qconnectivityglobal.h>
+#include "../qllcpserver_symbian_p.h"
+
+
+class CLlcpSocketType2;
+
+class CLlcpServer : public CBase,
+ public MLlcpConnOrientedListener
+ {
+public:
+ /*
+ * Creates a new CLlcpServer object.
+ */
+ static CLlcpServer* NewL(QLlcpServerPrivate&);
+
+ /*
+ * Destructor
+ */
+ ~CLlcpServer();
+
+public:
+ TBool Listen( const TDesC8& aServiceName);
+ void StopListening();
+ TBool isListening() const;
+ CLlcpSocketType2 *nextPendingConnection();
+ TBool hasPendingConnections() const;
+ const TDesC8& serviceUri() const;
+
+private: // From MLlcpConnOrientedListener
+ void RemoteConnectRequest( MLlcpConnOrientedTransporter* aConnection );
+
+private:
+ // Constructor
+ CLlcpServer(QLlcpServerPrivate&);
+
+ // Second phase constructor
+ void ConstructL();
+
+private:
+
+ RPointerArray<CLlcpSocketType2> iLlcpSocketArray;
+
+ /*
+ * Handle to NFC-server.
+ * Own.
+ */
+ RNfcServer iNfcServer;
+
+ /*
+ * Pointer to CLlcpProvider object.
+ * Own.
+ */
+ CLlcpProvider* iLlcp;
+
+ TBool iSocketListening;
+
+ RBuf8 iServiceName;
+
+ QLlcpServerPrivate& iCallback;
+ };
+
+#endif /* LLCPSERVER_SYMBIAN_H_ */
diff --git a/src/nfc/symbian/llcpsockettype1_symbian.cpp b/src/nfc/symbian/llcpsockettype1_symbian.cpp
new file mode 100644
index 00000000..3baf39fd
--- /dev/null
+++ b/src/nfc/symbian/llcpsockettype1_symbian.cpp
@@ -0,0 +1,857 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <llcpprovider.h> // CLlcpProvider
+#include <llcpconnlesstransporter.h> // MLlcpConnLessTransporter
+
+#include "nearfieldutility_symbian.h"
+#include "llcpsockettype1_symbian.h"
+#include "debug.h"
+
+
+/*
+ CLlcpSocketType1::NewL()
+*/
+CLlcpSocketType1* CLlcpSocketType1::NewL(QLlcpSocketPrivate& aCallback)
+ {
+ CLlcpSocketType1* self = CLlcpSocketType1::NewLC(aCallback);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/*
+ CLlcpSocketType1::NewLC()
+*/
+CLlcpSocketType1* CLlcpSocketType1::NewLC(QLlcpSocketPrivate& aCallback)
+ {
+ CLlcpSocketType1* self = new (ELeave) CLlcpSocketType1(aCallback);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+/*
+ CLlcpSocketType1::CLlcpSocketType1()
+*/
+CLlcpSocketType1::CLlcpSocketType1(QLlcpSocketPrivate& aCallback)
+ : iWaitStatus(ENone),
+ iPortBinded(EFalse),
+ iCallback(aCallback)
+ {
+ }
+
+/*
+ CLlcpSocketPrivate::ContructL()
+*/
+void CLlcpSocketType1::ConstructL()
+ {
+ User::LeaveIfError(iNfcServer.Open());
+ iLlcp = CLlcpProvider::NewL(iNfcServer);
+ iWait = new (ELeave) CActiveSchedulerWait;
+ }
+
+/*
+ Destroys the LLCP socket.
+*/
+CLlcpSocketType1::~CLlcpSocketType1()
+ {
+ BEGIN
+ // Destroy connection
+ Cleanup();
+
+ if (iLlcp)
+ {
+ iLlcp->StopListeningConnLessRequest(iLocalPort);
+ delete iLlcp;
+ }
+ iNfcServer.Close();
+ delete iTimer;
+ delete iWait;
+
+ END
+ }
+
+/*
+ Cancel the Receive/Transfer and destroy the local/remote connection.
+*/
+void CLlcpSocketType1::Cleanup()
+ {
+ BEGIN
+ // Deleting connection
+ if (iConnectionWrapper)
+ {
+ iConnectionWrapper->TransferCancel();
+ iConnectionWrapper->ReceiveCancel();
+ delete iConnectionWrapper;
+ iConnectionWrapper = NULL;
+ }
+ END
+ }
+
+/*
+ Start to listen the port as given, set as local port which is used to read datagram
+*/
+TBool CLlcpSocketType1::Bind(TUint8 aPortNum)
+ {
+ BEGIN
+ TBool bindOK = EFalse;
+ if (!iPortBinded)
+ {
+ TInt error = KErrNone;
+ TRAP(error, iLlcp->StartListeningConnLessRequestL(*this,aPortNum));
+ if (KErrNone == error)
+ {
+ iPortBinded = ETrue;
+ iLocalPort = aPortNum;
+ bindOK = ETrue;
+ }
+ }
+ END
+ return bindOK;
+ }
+
+/*
+ Sends the datagram at aData to the service that this socket is connected to.
+ Returns the number of bytes sent on success; otherwise return -1;
+*/
+TInt CLlcpSocketType1::StartWriteDatagram(const TDesC8& aData,TUint8 aPortNum)
+ {
+ BEGIN
+ TInt val = -1;
+
+ if (iConnectionWrapper != NULL && iRemotePort != aPortNum)
+ {
+ return val;
+ }
+
+ if (KErrNone == CreateConnection(aPortNum))
+ {
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error , iConnectionWrapper->TransferL(aData));
+
+ if (KErrNone == error)
+ {
+ iCallback.m_writeDatagramRefCount++;
+ val = 0;
+ }
+ }
+ END
+ return val;
+ }
+
+
+TInt CLlcpSocketType1::ReadDatagram(TDes8& aData, TUint8& aRemotePortNum)
+ {
+ BEGIN
+ aRemotePortNum = iRemotePort;
+ TInt val = ReadDatagram(aData);
+ END
+ return val;
+ }
+
+TInt CLlcpSocketType1::ReadDatagram(TDes8& aData)
+ {
+ BEGIN
+ TInt readSize = -1;
+ if (NULL != iConnectionWrapper)
+ {
+ readSize = iConnectionWrapper->ReceiveDataFromBuf(aData);
+
+ // Start receiving data again
+ TInt error = KErrNone;
+ error = iConnectionWrapper->Receive();
+ if (KErrNone != error)
+ {
+ readSize = -1;
+ }
+ }
+ END
+ return readSize;
+ }
+
+TBool CLlcpSocketType1::HasPendingDatagrams() const
+ {
+ BEGIN
+ TBool val = EFalse;
+ if (NULL != iConnectionWrapper)
+ {
+ val = iConnectionWrapper->HasPendingDatagrams();
+ }
+ END
+ return val;
+ }
+
+TInt64 CLlcpSocketType1::PendingDatagramSize() const
+ {
+ BEGIN
+ TInt64 val = -1;
+ if (NULL != iConnectionWrapper)
+ {
+ val = iConnectionWrapper->PendingDatagramSize();
+ }
+ END
+ return val;
+ }
+
+/*
+ Call back from MLlcpConnLessListener
+*/
+void CLlcpSocketType1::FrameReceived(MLlcpConnLessTransporter* aConnection)
+ {
+ BEGIN
+ iRemotePort = aConnection->SsapL();
+// StartTransportAndReceive(aConnection);
+ // Only accepting one incoming remote connection
+ TInt error = KErrNone;
+ if (iConnectionWrapper)
+ {
+ delete iConnectionWrapper;
+ iConnectionWrapper = NULL;
+ }
+ // Creating wrapper for connection.
+ TRAP(error, iConnectionWrapper = COwnLlcpConnectionWrapper::NewL(aConnection, *this));
+
+ if (error == KErrNone && iConnectionWrapper != NULL)
+ {
+ error = iConnectionWrapper->Receive();
+ }
+ if (error != KErrNone)
+ {
+ QT_TRYCATCH_ERROR(error,iCallback.invokeError());
+ }
+ END
+ }
+
+/*
+ Call back from MLlcpReadWriteCb
+*/
+void CLlcpSocketType1::ReceiveComplete(TInt aError)
+ {
+ BEGIN
+ TInt err = KErrNone;
+ if (KErrNone == aError)
+ {
+ QT_TRYCATCH_ERROR(err,iCallback.invokeReadyRead());
+ }
+ else
+ {
+ LOG("err = "<<err);
+ QT_TRYCATCH_ERROR(err,iCallback.invokeError());
+ }
+ Q_UNUSED(err);
+ END
+ }
+
+/*
+ Call back from MLlcpReadWriteCb
+*/
+void CLlcpSocketType1::WriteComplete(TInt aError, TInt aSize)
+ {
+ BEGIN
+ if (iWaitStatus == EWaitForBytesWritten)
+ {
+ StopWaitNow(EWaitForBytesWritten);
+ }
+
+ TInt err = KErrNone;
+ if (KErrNone == aError)
+ {
+ iCallback.m_writeDatagramRefCount--;
+ QT_TRYCATCH_ERROR(err,iCallback.invokeBytesWritten(aSize));
+ }
+ else
+ {
+ QT_TRYCATCH_ERROR(err,iCallback.invokeError());
+ }
+
+ if (err == aError && iConnectionWrapper != NULL
+ && iConnectionWrapper->HasQueuedWrittenDatagram())
+ {
+ iConnectionWrapper->TransferQueued();
+ }
+ END
+ }
+
+void CLlcpSocketType1::StopWaitNow(TWaitStatus aWaitStatus)
+ {
+ BEGIN
+ if (iWaitStatus == aWaitStatus)
+ {
+ if (iWait->IsStarted())
+ {
+ iWait->AsyncStop();
+ }
+ if (iTimer)//stop the timer
+ {
+ delete iTimer;
+ iTimer = NULL;
+ }
+ }
+ END
+ }
+
+/*
+ Creating MLlcpConnLessTransporter object if connection type connectionless,
+ Creating Creating wrapper for local peer connection.
+*/
+TInt CLlcpSocketType1::CreateConnection(TUint8 portNum)
+ {
+ BEGIN
+ TInt error = KErrNone;
+ MLlcpConnLessTransporter* llcpConnection = NULL;
+
+ if (iConnectionWrapper)
+ {
+ return error;
+ }
+
+ TRAP(error, llcpConnection = iLlcp->CreateConnLessTransporterL(portNum));
+
+ if (error == KErrNone)
+ {
+ iRemotePort = portNum;
+ error = StartTransportAndReceive(llcpConnection);
+ }
+ END
+ return error;
+ }
+
+TInt CLlcpSocketType1::StartTransportAndReceive(MLlcpConnLessTransporter* aConnection)
+ {
+ BEGIN
+ TInt error = KErrNone;
+
+ // Only accepting one incoming remote connection
+ if (!iConnectionWrapper)
+ {
+ // Creating wrapper for connection.
+ TRAP(error, iConnectionWrapper = COwnLlcpConnectionWrapper::NewL(aConnection, *this));
+ }
+
+ if (error == KErrNone && iConnectionWrapper != NULL)
+ {
+ error = iConnectionWrapper->Receive();
+ }
+ END
+ return error;
+ }
+
+
+TBool CLlcpSocketType1::WaitForBytesWritten(TInt aMilliSeconds)
+ {
+ BEGIN_END
+ return WaitForOperationReady(EWaitForBytesWritten, aMilliSeconds);
+ }
+
+TBool CLlcpSocketType1::WaitForOperationReady(TWaitStatus aWaitStatus,TInt aMilliSeconds)
+ {
+ BEGIN
+ TBool ret = EFalse;
+ if (iWaitStatus != ENone || iWait->IsStarted())
+ {
+ return ret;
+ }
+ iWaitStatus = aWaitStatus;
+
+ if (iTimer)
+ {
+ delete iTimer;
+ iTimer = NULL;
+ }
+ if (aMilliSeconds > 0)
+ {
+ TRAPD(err, iTimer = CLlcpTimer::NewL(*iWait));
+ if (err != KErrNone)
+ {
+ return ret;
+ }
+ iTimer->Start(aMilliSeconds);
+ }
+ iWait->Start();
+
+ //control is back here when iWait->AsyncStop() is called by the timer or the callback function
+ iWaitStatus = ENone;
+
+ if (!iTimer)
+ {
+ //iTimer == NULL means this CActiveSchedulerWait
+ //AsyncStop is fired by the call back of ReadyRead
+ ret = ETrue;
+ }
+ else
+ {
+ delete iTimer;
+ iTimer = NULL;
+ }
+
+ END
+ return ret;
+ }
+
+
+/*
+ Construct the wrapper for connectionLess transport.
+*/
+COwnLlcpConnectionWrapper* COwnLlcpConnectionWrapper::NewL(MLlcpConnLessTransporter* aConnection
+ , MLlcpReadWriteCb& aCallBack)
+ {
+ COwnLlcpConnectionWrapper* self = COwnLlcpConnectionWrapper::NewLC(aConnection, aCallBack);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/*
+ Construct the new wrapper for connectionLess transport.
+*/
+COwnLlcpConnectionWrapper* COwnLlcpConnectionWrapper::NewLC(MLlcpConnLessTransporter* aConnection
+ , MLlcpReadWriteCb& aCallBack)
+ {
+ COwnLlcpConnectionWrapper* self = new (ELeave) COwnLlcpConnectionWrapper(aConnection);
+ CleanupStack::PushL(self);
+ self->ConstructL(aCallBack);
+ return self;
+ }
+
+/*
+ Constructor
+*/
+COwnLlcpConnectionWrapper::COwnLlcpConnectionWrapper(MLlcpConnLessTransporter* aConnection)
+ : iConnection(aConnection)
+ {
+ }
+
+/*
+ ConstructL
+*/
+void COwnLlcpConnectionWrapper::ConstructL(MLlcpReadWriteCb& aCallBack)
+ {
+ if (NULL == iConnection)
+ {
+ User::Leave(KErrArgument);
+ }
+ // Create the transmitter AO
+ iSenderAO = CLlcpSenderType1::NewL(*iConnection, aCallBack);
+ // Create the receiver AO
+ iReceiverAO = CLlcpReceiverType1::NewL(*iConnection, aCallBack);
+ }
+
+/*
+ Destroy the new wrapper for connectionLess transport.
+*/
+COwnLlcpConnectionWrapper::~COwnLlcpConnectionWrapper()
+ {
+ BEGIN
+ iSendBufArray.ResetAndDestroy();
+ iSendBufArray.Close();
+
+ delete iSenderAO;
+ delete iReceiverAO;
+
+ if (iConnection)
+ {
+ delete iConnection;
+ iConnection = NULL;
+ }
+ END
+ }
+
+/*
+ Send data from queued buffer
+*/
+bool COwnLlcpConnectionWrapper::TransferQueued()
+ {
+ BEGIN
+ bool ret = false;
+ if (iSendBufArray.Count() == 0 || iSenderAO->IsActive())
+ return ret;
+
+ HBufC8* bufRef = iSendBufArray[0];
+ if (NULL == bufRef)
+ return ret;
+
+ TPtrC8 ptr(bufRef->Ptr(), bufRef->Length());
+ if(!iSenderAO->IsActive() && iSenderAO->Transfer(ptr) == KErrNone)
+ {
+ ret = true;
+ }
+ iSendBufArray.Remove(0);
+ delete bufRef;
+ bufRef = NULL;
+
+ END
+ return ret;
+ }
+
+/*
+ Send data from local peer to remote peer via connectionLess transport
+*/
+TInt COwnLlcpConnectionWrapper::TransferL(const TDesC8& aData)
+ {
+ BEGIN
+ TInt error = KErrNone;
+ // Pass message into transmitter AO
+ if (!iSenderAO->IsActive())
+ {
+ error = iSenderAO->Transfer(aData);
+ }
+ else if (aData.Length() > 0)
+ {
+ HBufC8* buf = HBufC8::NewLC(aData.Length());
+ buf->Des().Copy(aData);
+ error = iSendBufArray.Append(buf);
+ CleanupStack::Pop(buf);
+ }
+ END
+ return error;
+ }
+
+
+/*
+ * Trigger the receiver AO to start receive datagram
+ Receive data from remote peer to local peer via connectionLess transport
+*/
+TInt COwnLlcpConnectionWrapper::Receive()
+ {
+ BEGIN
+ TInt error = KErrInUse;
+ // Pass message on to transmit AO
+ if (!iReceiverAO->IsActive())
+ {
+ error = iReceiverAO->Receive();
+ }
+
+ END
+ return error;
+ }
+
+/*
+ Retrieve data from the buffer of the connection less socket
+*/
+TInt COwnLlcpConnectionWrapper::ReceiveDataFromBuf(TDes8& aData)
+ {
+ return iReceiverAO->ReceiveDataFromBuf(aData);
+ }
+
+bool COwnLlcpConnectionWrapper::HasPendingDatagrams() const
+ {
+ return iReceiverAO->HasPendingDatagrams();
+ }
+
+bool COwnLlcpConnectionWrapper::HasQueuedWrittenDatagram() const
+ {
+ bool hasData = iSendBufArray.Count() > 0 ? true : false;
+ return hasData;
+ }
+
+TInt64 COwnLlcpConnectionWrapper::PendingDatagramSize() const
+ {
+ return iReceiverAO->PendingDatagramSize();
+ }
+
+/*
+ Cancel data transfer from local peer to remote peer via connectionLess transport
+*/
+void COwnLlcpConnectionWrapper::TransferCancel()
+ {
+ BEGIN
+ if (iSenderAO->IsActive())
+ {
+ iSenderAO->Cancel();
+ }
+ END
+ }
+
+/*
+ Cancel data receive from local peer to remote peer via connectionLess transport
+*/
+void COwnLlcpConnectionWrapper::ReceiveCancel()
+ {
+ BEGIN
+ if (iReceiverAO->IsActive())
+ {
+ iReceiverAO->Cancel();
+ }
+ END
+ }
+
+/*
+ Start of implementation of Sender AO & Receiver AO for connection less mode (type1)
+*/
+
+/*
+ Constructor
+*/
+CLlcpSenderType1::CLlcpSenderType1(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack)
+ : CActive(CActive::EPriorityStandard)
+ , iConnection(aConnection)
+ , iSendObserver(aCallBack)
+ {
+ }
+
+/*
+ Constructor
+*/
+CLlcpSenderType1* CLlcpSenderType1::NewL(MLlcpConnLessTransporter& iConnection, MLlcpReadWriteCb& aCallBack)
+ {
+ CLlcpSenderType1* self = new(ELeave) CLlcpSenderType1(iConnection, aCallBack);
+ CActiveScheduler::Add(self);
+ return self;
+ }
+
+/*
+ Destructor
+*/
+CLlcpSenderType1::~CLlcpSenderType1()
+ {
+ BEGIN
+ Cancel(); // Cancel ANY outstanding request at time of destruction
+ iTransmitBuf.Close();
+ iTempSendBuf.Close();
+ END
+ }
+
+TInt CLlcpSenderType1::Transfer(const TDesC8& aData)
+ {
+ BEGIN
+
+ if (aData.Length() == 0)
+ {
+ return KErrArgument;
+ }
+
+ TInt supportedDataLength = iConnection.SupportedDataLength();
+ if (supportedDataLength <= 0)
+ {
+ return KErrNotReady;
+ }
+ // Reset pos to start
+ iCurrentSendBufPos = 0;
+ TInt error = KErrNone;
+ // Copying data to internal buffer.
+ iTransmitBuf.Zero();
+ error = iTransmitBuf.ReAlloc(aData.Length());
+
+ if (error == KErrNone)
+ {
+ iTransmitBuf.Append(aData);
+
+ if (iTransmitBuf.Length() > supportedDataLength)
+ {
+ iCurrentSendBufPtr.Set(iTransmitBuf.Ptr(), supportedDataLength);
+ }
+ else
+ {
+ iCurrentSendBufPtr.Set(iTransmitBuf.Ptr(), iTransmitBuf.Length());
+ }
+ iCurrentSendBufPos = iCurrentSendBufPtr.Length();
+ // Sending data, don't need check active, external func has checked it
+ iTempSendBuf.Close();
+ iTempSendBuf.Create(iCurrentSendBufPtr);
+ iConnection.Transmit(iStatus, iTempSendBuf);
+ SetActive();
+ }
+ else
+ {
+ error = KErrNoMemory;
+ }
+ END
+ return error;
+ }
+
+void CLlcpSenderType1::RunL(void)
+ {
+ BEGIN
+ TInt error = iStatus.Int();
+ // Sending error, notify user
+ if (KErrNone != error)
+ {
+ // Return buffer's length which has been sent successfully.
+ iSendObserver.WriteComplete(error, iCurrentSendBufPos - iCurrentSendBufPtr.Length());
+ return;
+ }
+
+ TInt bytesWritten = iCurrentSendBufPtr.Length();
+
+ // Still have some buffer need send, don't stop
+ if (iCurrentSendBufPos < iTransmitBuf.Length())
+ {
+ TInt supportedDataLength = iConnection.SupportedDataLength();
+ if (supportedDataLength <= 0)
+ {
+ iSendObserver.WriteComplete(KErrGeneral, iCurrentSendBufPtr.Length());
+ return;
+ }
+
+ if (iTransmitBuf.Length() > iCurrentSendBufPos + supportedDataLength)
+ {
+ // Still left some buffer
+ iCurrentSendBufPtr.Set(iTransmitBuf.Ptr() + iCurrentSendBufPos, supportedDataLength);
+ iCurrentSendBufPos += supportedDataLength;
+ }
+ else
+ {
+ // All buffer will be sent in this time
+ iCurrentSendBufPtr.Set(iTransmitBuf.Ptr() + iCurrentSendBufPos
+ , iTransmitBuf.Length() - iCurrentSendBufPos);
+ iCurrentSendBufPos = iTransmitBuf.Length();
+ }
+ // Sending data
+ iTempSendBuf.Close();
+ iTempSendBuf.Create(iCurrentSendBufPtr);
+ iConnection.Transmit(iStatus, iTempSendBuf);
+ SetActive();
+ }
+ // Sent signal for each successful sending
+ iSendObserver.WriteComplete(error, bytesWritten);
+ END
+ }
+
+void CLlcpSenderType1::DoCancel(void)
+ {
+ BEGIN
+ // Cancel any outstanding write request on iSocket at this time.
+ iConnection.TransmitCancel();
+ END
+ }
+
+/*
+ Start of implementation of Receiver AO for connection less mode (type1) - CLlcpReceiverType1
+*/
+
+/*
+ Constructor
+*/
+CLlcpReceiverType1::CLlcpReceiverType1(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack)
+ : CActive(CActive::EPriorityStandard)
+ , iConnection(aConnection)
+ , iReceiveObserver(aCallBack)
+ {
+ }
+
+/*
+ Constructor
+*/
+CLlcpReceiverType1* CLlcpReceiverType1::NewL(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack)
+ {
+ CLlcpReceiverType1* self = new (ELeave) CLlcpReceiverType1(aConnection, aCallBack);
+ CActiveScheduler::Add(self);
+ return self;
+ }
+
+
+/*
+ Set active for the receiver AO
+ Receive complete callback function "cb" registered
+*/
+TInt CLlcpReceiverType1::Receive()
+ {
+ BEGIN
+ TInt error = KErrNotReady;
+ TInt length = 0;
+ length = iConnection.SupportedDataLength();
+ iReceiveBuf.Zero();
+ if (length > 0)
+ error = iReceiveBuf.ReAlloc(length);
+
+ if (error == KErrNone)
+ {
+ iConnection.Receive(iStatus, iReceiveBuf);
+ SetActive();
+ }
+
+ END
+ return error;
+ }
+
+void CLlcpReceiverType1::RunL(void)
+ {
+ BEGIN
+ TInt error = iStatus.Int();
+ // Call back functions of notifying the llcp receiver completed.
+ iReceiveObserver.ReceiveComplete(error);
+ END
+ }
+
+CLlcpReceiverType1::~CLlcpReceiverType1()
+ {
+ BEGIN
+ // cancel ANY outstanding request at time of destruction
+ Cancel();
+ iReceiveBuf.Close();
+ END
+ }
+
+TInt CLlcpReceiverType1::ReceiveDataFromBuf(TDes8& aData)
+ {
+ BEGIN
+ if (iReceiveBuf.Size() == 0)
+ return 0;
+
+ TInt requiredLength = aData.MaxLength() - aData.Length();
+ TInt bufLength = iReceiveBuf.Length();
+ TInt readLength = requiredLength < bufLength ? requiredLength : bufLength;
+
+ TPtrC8 ptr(iReceiveBuf.Ptr(),readLength);
+ aData.Append(ptr);
+
+ //Empty the buffer as long as receive data request issued.
+ iReceiveBuf.Zero();
+ END
+ return readLength;
+ }
+
+bool CLlcpReceiverType1::HasPendingDatagrams() const
+ {
+ return iReceiveBuf.Size() > 0 ? true : false;
+ }
+
+TInt64 CLlcpReceiverType1::PendingDatagramSize() const
+ {
+ return iReceiveBuf.Size();
+ }
+
+void CLlcpReceiverType1::DoCancel(void)
+ {
+ BEGIN
+ // Cancel any outstanding write request on iSocket at this time.
+ iConnection.ReceiveCancel();
+ END
+ }
diff --git a/src/nfc/symbian/llcpsockettype1_symbian.h b/src/nfc/symbian/llcpsockettype1_symbian.h
new file mode 100644
index 00000000..d45e20e9
--- /dev/null
+++ b/src/nfc/symbian/llcpsockettype1_symbian.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LLCPSOCKETTYPE1_SYMBIAN_H_
+#define LLCPSOCKETTYPE1_SYMBIAN_H_
+
+#include <e32base.h>
+#include <nfcserver.h> // RNfcServer
+#include <llcpconnlesslistener.h> // MLlcpConnLessListener
+
+/*
+ * FORWARD DECLARATIONS
+ */
+class COwnLlcpConnectionWrapper;
+class CLlcpSenderType1;
+class CLlcpReceiverType1;
+class CLlcpTimer;
+class CLlcpProvider;
+class MLlcpConnLessTransporter;
+
+#include <qconnectivityglobal.h>
+#include "../qllcpsocket_symbian_p.h"
+
+class MLlcpReadWriteCb
+ {
+public:
+
+ /*
+ * Empty Destructor.
+ */
+ virtual ~MLlcpReadWriteCb() {};
+
+ /*
+ * Called
+ */
+ virtual void ReceiveComplete(TInt aError) = 0;
+ virtual void WriteComplete(TInt aError, TInt aSize) = 0;
+ };
+
+/*
+ * CLASS DECLARATION for CLlcpSocketType1 (ConnectLess Tran).
+ */
+class CLlcpSocketType1 : public CBase,
+ public MLlcpConnLessListener,
+ public MLlcpReadWriteCb
+ {
+public:
+ /*
+ * Creates a new CLlcpSocketType1 object.
+ */
+ static CLlcpSocketType1* NewL(QLlcpSocketPrivate&);
+
+ /*
+ * Creates a new CLlcpSocketType1 object.
+ */
+ static CLlcpSocketType1* NewLC(QLlcpSocketPrivate&);
+
+ /*
+ * Destructor
+ */
+ ~CLlcpSocketType1();
+
+public:
+ TInt StartWriteDatagram(const TDesC8& aData,TUint8 portNum);
+ TInt ReadDatagram(TDes8& aData);
+ TInt ReadDatagram(TDes8& aData, TUint8& aRemotePortNum);
+ TBool Bind(TUint8 portNum);
+
+ /*
+ Returns true if at least one datagram is waiting to be read;
+ otherwise returns false.
+ */
+ TBool HasPendingDatagrams() const;
+ TInt64 PendingDatagramSize() const;
+ TBool WaitForBytesWritten(TInt aMilliSeconds);
+
+private:
+ enum TWaitStatus
+ {
+ ENone,
+ EWaitForBytesWritten
+ };
+
+private:
+ TBool WaitForOperationReady(TWaitStatus aWaitStatus,TInt aMilliSeconds);
+ void StopWaitNow(TWaitStatus aWaitStatus);
+
+private: // from MLlcpReadWriteCb
+ void ReceiveComplete(TInt aError);
+ void WriteComplete(TInt aError, TInt aSize);
+
+private: // From MLlcpConnLessListener
+ void FrameReceived(MLlcpConnLessTransporter* aConnection);
+
+private:
+ // Constructor
+ CLlcpSocketType1(QLlcpSocketPrivate&);
+
+ // Second phase constructor
+ void ConstructL();
+ void Cleanup();
+
+ TInt CreateConnection(TUint8 portNum);
+ TInt StartTransportAndReceive(MLlcpConnLessTransporter* aConnection);
+
+private:
+ /*
+ * Handle to NFC-server.
+ * Own.
+ */
+ RNfcServer iNfcServer;
+
+ /*
+ * Pointer to CLlcpProvider object.
+ * Own.
+ */
+ CLlcpProvider* iLlcp; // Own
+
+ /*
+ * Pointer to MLlcpConnLessTransporter object.
+ * Own.
+ *
+ * This is used to send data to local device.
+ */
+ COwnLlcpConnectionWrapper* iConnectionWrapper; // Own
+
+ CActiveSchedulerWait * iWait; //Own
+ CLlcpTimer * iTimer; // Own
+ TWaitStatus iWaitStatus;
+
+ bool iPortBinded;
+ TUint8 iLocalPort;
+ TUint8 iRemotePort;
+
+ QLlcpSocketPrivate& iCallback;
+ };
+
+/*
+ * CLASS DECLARATION for COwnLlcpConnectionWrapper.
+ *
+ */
+class COwnLlcpConnectionWrapper : public CBase
+ {
+public:
+
+ /*
+ * Creates a new COwnLlcpConnection object.
+ */
+ static COwnLlcpConnectionWrapper* NewL(MLlcpConnLessTransporter* aTransporter
+ , MLlcpReadWriteCb& aCallBack);
+
+ /*
+ * Creates a new COwnLlcpConnection object.
+ */
+ static COwnLlcpConnectionWrapper* NewLC(MLlcpConnLessTransporter* aTransporter
+ , MLlcpReadWriteCb& aCallBack);
+
+ /*
+ * Destructor.
+ */
+ ~COwnLlcpConnectionWrapper();
+
+public:
+ /*
+ * Transfer given data to remote device.
+ */
+ TInt TransferL(const TDesC8& aData);
+ bool TransferQueued();
+ void TransferCancel();
+ TInt Receive();
+
+ /*
+ * Cancels COwnLlcpConnection::Receive() request.
+ */
+ void ReceiveCancel();
+
+ TInt ReceiveDataFromBuf(TDes8& aData);
+ bool HasPendingDatagrams() const;
+ TInt64 PendingDatagramSize() const;
+ bool HasQueuedWrittenDatagram() const;
+
+private:
+
+ // Constructor
+ COwnLlcpConnectionWrapper(MLlcpConnLessTransporter* aConnection);
+ // Second phase constructor
+ void ConstructL(MLlcpReadWriteCb& aCallBack);
+
+private:
+ MLlcpConnLessTransporter* iConnection;
+ CLlcpSenderType1* iSenderAO;
+ CLlcpReceiverType1* iReceiverAO;
+ RPointerArray<HBufC8> iSendBufArray;
+ };
+
+
+class CLlcpSenderType1 : public CActive
+ {
+public:
+ static CLlcpSenderType1* NewL(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack);
+ ~CLlcpSenderType1();
+
+public:
+ /*
+ * Transfer given data to remote device.
+ */
+ TInt Transfer(const TDesC8& aData);
+
+ /*
+ * Cancels COwnLlcpConnection::Transfer() request.
+ */
+ void TransferCancel();
+
+public: // From CActive
+ void RunL();
+ void DoCancel();
+
+private:
+ CLlcpSenderType1(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack);
+private:
+ /*
+ Buffered data for transmitting data.
+ */
+ MLlcpConnLessTransporter& iConnection;
+ MLlcpReadWriteCb& iSendObserver;
+ RBuf8 iTransmitBuf;
+ // Symbian have limitaion for sending buffer in one send,
+ // The variable used to record how many buffer have been sent so far
+ TInt iCurrentSendBufPos;
+ TPtrC8 iCurrentSendBufPtr;
+ RBuf8 iTempSendBuf; // Temp workround to avoid NFC server's bug, if use ptr, it will crash
+ };
+
+class CLlcpReceiverType1 : public CActive
+ {
+public:
+ static CLlcpReceiverType1* NewL(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack);
+ ~CLlcpReceiverType1();
+
+public:
+ /*
+ * Starts receive data from ConnLess.
+ */
+ TInt Receive();
+
+ /*
+ * Cancels COwnLlcpConnection::Receive() request.
+ */
+ void ReceiveCancel();
+ TInt ReceiveDataFromBuf(TDes8& aData);
+
+ bool HasPendingDatagrams() const;
+ TInt64 PendingDatagramSize() const;
+
+public: // From CActive
+ void RunL();
+ void DoCancel();
+
+private:
+ CLlcpReceiverType1(MLlcpConnLessTransporter& aConnection, MLlcpReadWriteCb& aCallBack);
+
+private:
+ RBuf8 iReceiveBuf;
+ MLlcpConnLessTransporter& iConnection;
+ MLlcpReadWriteCb& iReceiveObserver;
+ };
+#endif /* LLCPSOCKETTYPE1_SYMBIAN_H_ */
diff --git a/src/nfc/symbian/llcpsockettype2_symbian.cpp b/src/nfc/symbian/llcpsockettype2_symbian.cpp
new file mode 100644
index 00000000..0cc92d2b
--- /dev/null
+++ b/src/nfc/symbian/llcpsockettype2_symbian.cpp
@@ -0,0 +1,986 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nearfieldutility_symbian.h"
+#include "llcpsockettype2_symbian.h"
+
+#include "debug.h"
+
+/*
+ CLlcpSocketType2::ContructL()
+*/
+void CLlcpSocketType2::ConstructL()
+ {
+ BEGIN
+ User::LeaveIfError(iNfcServer.Open());
+ iLlcp = CLlcpProvider::NewL( iNfcServer );
+ iWait = new (ELeave) CActiveSchedulerWait;
+ END
+ }
+
+/*
+ CLlcpSocketType2::CLlcpSocketType2()
+*/
+CLlcpSocketType2::CLlcpSocketType2(MLlcpConnOrientedTransporter* aTransporter, QLlcpSocketPrivate* aCallback)
+ : iLlcp( NULL ),
+ iTransporter(aTransporter),
+ iWaitStatus(ENone),
+ iCallback(aCallback)
+ {
+ }
+
+CLlcpSocketType2* CLlcpSocketType2::NewL(QLlcpSocketPrivate* aCallback)
+ {
+ BEGIN
+ CLlcpSocketType2* self = new (ELeave) CLlcpSocketType2(NULL,aCallback);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ END
+ return self;
+ }
+
+CLlcpSocketType2* CLlcpSocketType2::NewL(MLlcpConnOrientedTransporter* aTransporter, QLlcpSocketPrivate* aCallback)
+ {
+ BEGIN
+ CLlcpSocketType2* self = new (ELeave) CLlcpSocketType2(aTransporter,aCallback);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ END
+ return self;
+ }
+
+/*
+ Destroys the LLCP socket.
+*/
+CLlcpSocketType2::~CLlcpSocketType2()
+ {
+ BEGIN
+ delete iConnecter;
+ delete iSender;
+ delete iReceiver;
+ delete iTransporter;
+ delete iLlcp;
+ delete iWait;
+ delete iTimer;
+ iReceiveBufArray.ResetAndDestroy();
+ iReceiveBufArray.Close();
+ iNfcServer.Close();
+ END
+ }
+
+/*
+ Connects to the service identified by the URI \a serviceUri (on \a target).
+*/
+void CLlcpSocketType2::ConnectToServiceL( const QString &serviceUri)
+ {
+ BEGIN
+ HBufC8* serviceName = QNFCNdefUtility::QString2HBufC8L(serviceUri);
+
+ CleanupStack::PushL(serviceName);
+ ConnectToServiceL(serviceName->Des()) ;
+ CleanupStack::PopAndDestroy(serviceName);
+ END
+ }
+
+void CLlcpSocketType2::ConnectToServiceL( const TDesC8& aServiceName)
+ {
+ BEGIN
+ if ( !iConnecter && !iTransporter)
+ {
+ iTransporter = iLlcp->CreateConnOrientedTransporterL( aServiceName );
+ iConnecter = CLlcpConnecterAO::NewL( *iTransporter, *this );
+ }
+ iConnecter->ConnectL( aServiceName );
+ END
+ }
+
+/*
+ Disconnects the socket.
+*/
+
+TInt CLlcpSocketType2::DisconnectFromService()
+ {
+ BEGIN
+ if (iSender && iSender->IsActive())
+ {
+ WaitForBytesWritten(3000);//wait 3 seconds
+ }
+ if (iSender)
+ {
+ delete iSender;
+ iSender = NULL;
+ }
+ if (iReceiver)
+ {
+ delete iReceiver;
+ iReceiver = NULL;
+ }
+
+ if (iConnecter)
+ {
+ iConnecter->Disconnect();
+ delete iConnecter;
+ iConnecter = NULL;
+ }
+ if (iTransporter)
+ {
+ LOG("delete iTransporter;");
+ delete iTransporter;
+ iTransporter = NULL;
+ }
+ END
+ return KErrNone;
+ }
+
+/*
+ Sends the datagram at aData to the service that this socket is connected to.
+ Returns the number of bytes sent on success; otherwise return -1;
+*/
+TInt CLlcpSocketType2::StartWriteDatagram(const TDesC8& aData)
+ {
+ BEGIN
+ TInt val = -1;
+ if (!iTransporter)
+ {
+ END
+ return val;
+ }
+
+ if (!iSender)
+ {
+ TRAPD(err,iSender = CLlcpSenderAO::NewL(*iTransporter, *this));
+ if (err != KErrNone)
+ {
+ END
+ return val;
+ }
+ }
+ TInt error = KErrNone;
+ //asynchronous transfer
+ error = iSender->Send( aData);
+ if (KErrNone == error)
+ {
+ val = 0;
+ }
+ END
+ return val;
+ }
+
+TBool CLlcpSocketType2::ReceiveData(TDes8& aData)
+ {
+ //fetch data from internal buffer
+ BEGIN
+ TBool ret = EFalse;
+ HBufC8* buf = NULL;
+ TInt extBufferLength = aData.Length();
+ TInt extBufferMaxLength = aData.MaxLength();
+ while ( iReceiveBufArray.Count() > 0 )
+ {
+ buf = iReceiveBufArray[ 0 ];
+ if (buf->Length() - iBufferOffset <= extBufferMaxLength - extBufferLength )
+ {//internal buffer's size <= available space of the user specified buffer
+ TPtrC8 ptr(buf->Ptr() + iBufferOffset, buf->Length() - iBufferOffset);
+ aData.Append( ptr );
+ iReceiveBufArray.Remove( 0 );
+ extBufferLength += buf->Length() - iBufferOffset;
+ delete buf;
+ buf = NULL;
+ iBufferOffset = 0;
+ }
+ else
+ {
+ TPtrC8 ptr(buf->Ptr() + iBufferOffset, extBufferMaxLength - extBufferLength);
+ aData.Append( ptr );
+ iBufferOffset += extBufferMaxLength - extBufferLength;
+ ret = ETrue;
+ break;
+ }
+ ret = ETrue;
+ }
+ END
+ return ret;
+ }
+
+TInt64 CLlcpSocketType2::BytesAvailable()
+ {
+ BEGIN
+ TInt64 ret = 0;
+ for (TInt i = 0; i < iReceiveBufArray.Count(); ++i)
+ {
+ HBufC8* buf = iReceiveBufArray[ i ];
+ if (!buf)
+ {
+ continue;
+ }
+ if ( i == 0)
+ {
+ ret += buf->Length() - iBufferOffset;
+ }
+ else
+ {
+ ret += buf->Length();
+ }
+ }
+ END
+ return ret;
+ }
+
+TBool CLlcpSocketType2::WaitForOperationReady(TWaitStatus aWaitStatus,TInt aMilliSeconds)
+ {
+ BEGIN
+ TBool ret = EFalse;
+ if (iWaitStatus != ENone || iWait->IsStarted())
+ {
+ END
+ return ret;
+ }
+ iWaitStatus = aWaitStatus;
+
+ if (iTimer)
+ {
+ delete iTimer;
+ iTimer = NULL;
+ }
+ if (aMilliSeconds > 0)
+ {
+ TRAPD(err, iTimer = CLlcpTimer::NewL(*iWait));
+ if (err != KErrNone)
+ {
+ END
+ return ret;
+ }
+ iTimer->Start(aMilliSeconds);
+ }
+ iWait->Start();
+ //control is back here when iWait->AsyncStop() is called by the timer or the callback function
+ iWaitStatus = ENone;
+
+ if (!iTimer)
+ {
+ //iTimer == NULL means this CActiveSchedulerWait
+ //AsyncStop is fired by the call back of ReadyRead
+ ret = ETrue;
+ }
+ else
+ {
+ delete iTimer;
+ iTimer = NULL;
+ }
+ END
+ return ret;
+ }
+
+/**
+ * Blocks until data is available for reading and the readyRead()
+ * signal has been emitted, or until msecs milliseconds have
+ * passed. If msecs is -1, this function will not time out.
+ * Returns true if data is available for reading; otherwise
+ * returns false (if the operation timed out or if an error
+ * occurred).
+ */
+TBool CLlcpSocketType2::WaitForReadyRead(TInt aMilliSeconds)
+ {
+ BEGIN
+ END
+ return WaitForOperationReady(EWaitForReadyRead, aMilliSeconds);
+ }
+
+TBool CLlcpSocketType2::WaitForBytesWritten(TInt aMilliSeconds)
+ {
+ BEGIN
+ END
+ return WaitForOperationReady(EWaitForBytesWritten, aMilliSeconds);
+ }
+TBool CLlcpSocketType2::WaitForConnected(TInt aMilliSeconds)
+ {
+ BEGIN
+ END
+ return WaitForOperationReady(EWaitForConnected, aMilliSeconds);
+ }
+
+void CLlcpSocketType2::AttachCallbackHandler(QLlcpSocketPrivate* aCallback)
+ {
+ BEGIN
+ iCallback = aCallback;
+ if (iTransporter && iTransporter->IsConnected())//has connected llcp transporter
+ {
+ LOG("A server llcp type2 socket");
+ if (!iReceiver)
+ {
+ TRAPD(err,iReceiver = CLlcpReceiverAO::NewL( *iTransporter, *this ));
+ if (err != KErrNone)
+ {
+ END
+ return;
+ }
+ }
+ if (!iConnecter)
+ {
+ TRAP_IGNORE(iConnecter = CLlcpConnecterAO::NewL( *iTransporter, *this ));
+ }
+ if (iReceiver->StartReceiveDatagram() != KErrNone)
+ {
+ Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+ END
+ }
+
+void CLlcpSocketType2::Error(QLlcpSocket::SocketError /*aSocketError*/)
+ {
+ BEGIN
+ //emit error
+ if ( iCallback )
+ {
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error,iCallback->invokeError());
+ //can do nothing if there is an error,so just ignore it
+ Q_UNUSED(error);
+ }
+ END
+ }
+void CLlcpSocketType2::StateChanged(QLlcpSocket::SocketState aSocketState)
+ {
+ BEGIN
+ if (aSocketState == QLlcpSocket::ConnectedState && iWaitStatus == EWaitForConnected)
+ {
+ StopWaitNow(EWaitForConnected);
+ }
+ TInt error = KErrNone;
+ if (aSocketState == QLlcpSocket::ConnectedState)
+ {
+ if ( iCallback)
+ {
+ QT_TRYCATCH_ERROR(error, iCallback->invokeConnected());
+ Q_UNUSED(error);
+ }
+ if (!iReceiver)
+ {
+ TRAPD(err,iReceiver = CLlcpReceiverAO::NewL( *iTransporter, *this ));
+ if (err != KErrNone)
+ {
+ Error(QLlcpSocket::UnknownSocketError);
+ return;
+ }
+ }
+ if(iReceiver->StartReceiveDatagram() != KErrNone)
+ {
+ Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+
+ if (aSocketState == QLlcpSocket::ClosingState && iCallback)
+ {
+ QT_TRYCATCH_ERROR(error, iCallback->invokeDisconnected());
+ Q_UNUSED(error);
+ }
+
+ END
+ }
+
+void CLlcpSocketType2::StopWaitNow(TWaitStatus aWaitStatus)
+ {
+ BEGIN
+ if ( iWaitStatus == aWaitStatus )
+ {
+ if (iTimer)//stop the timer
+ {
+ delete iTimer;
+ iTimer = NULL;
+ }
+ if (iWait->IsStarted())
+ {
+ iWait->AsyncStop();
+ }
+ }
+ END
+ }
+void CLlcpSocketType2::ReadyRead()
+ {
+ BEGIN
+ if (iWaitStatus == EWaitForReadyRead)
+ {
+ StopWaitNow(EWaitForReadyRead);
+ }
+ //emit readyRead()
+ if ( iCallback )
+ {
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error,iCallback->invokeReadyRead());
+ //can do nothing if there is an error,so just ignore it
+ Q_UNUSED(error);
+ }
+ END
+ }
+void CLlcpSocketType2::BytesWritten(qint64 aBytes)
+ {
+ BEGIN
+ if (iWaitStatus == EWaitForBytesWritten)
+ {
+ StopWaitNow(EWaitForBytesWritten);
+ }
+ //emit bytesWritten signal;
+ if ( iCallback )
+ {
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error,iCallback->invokeBytesWritten(aBytes));
+ //can do nothing if there is an error,so just ignore it
+ Q_UNUSED(error);
+ }
+ END
+ }
+
+// connecter implementation
+CLlcpConnecterAO* CLlcpConnecterAO::NewL( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket )
+ {
+ BEGIN
+ CLlcpConnecterAO* self = new (ELeave) CLlcpConnecterAO( aConnection, aSocket );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ END
+ return self;
+ }
+
+CLlcpConnecterAO::CLlcpConnecterAO( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket )
+ : CActive( EPriorityStandard ),
+ iConnection( aConnection ),
+ iSocket( aSocket ),
+ iConnState( ENotConnected )
+ {
+ }
+/*
+ ConstructL
+*/
+void CLlcpConnecterAO::ConstructL()
+ {
+ BEGIN
+ CActiveScheduler::Add( this );
+ if ( iConnection.IsConnected() )
+ {
+ LOG("a LLCP server side socket");
+ iConnState = EConnected;
+ // Starting listening disconnect event
+ iConnection.WaitForDisconnection( iStatus );
+ SetActive();
+ }
+ END
+ }
+
+/*
+ * Destructor.
+ */
+CLlcpConnecterAO::~CLlcpConnecterAO()
+ {
+ BEGIN
+ Cancel();
+ if ( iConnState == EConnected )
+ {
+ iConnection.Disconnect();
+ }
+ END
+ }
+/*
+ * Connect to remote peer as given service uri.
+ */
+void CLlcpConnecterAO::ConnectL(const TDesC8& /*aServiceName*/)
+ {
+ BEGIN
+ if ( iConnState == ENotConnected )
+ {
+ // Starting connecting if is in idle state
+ iConnection.Connect( iStatus );
+ SetActive();
+ iConnState = EConnecting;
+ //emit connecting signal
+ iSocket.StateChanged(QLlcpSocket::ConnectingState);
+ }
+ END
+ }
+
+/*
+ * Disconnect with remote peer.
+ */
+void CLlcpConnecterAO::Disconnect()
+ {
+ BEGIN
+ if ( iConnState == ENotConnected )
+ {
+ END
+ return;
+ }
+ Cancel();
+ if ( iConnState == EConnected )
+ {
+ iConnection.Disconnect();
+ }
+ iConnState = ENotConnected;
+
+ //emit QAbstractSocket::ClosingState;
+ iSocket.StateChanged(QLlcpSocket::ClosingState);
+ END
+ }
+void CLlcpConnecterAO::RunL()
+ {
+ BEGIN
+ TInt error = iStatus.Int();
+
+ switch ( iConnState )
+ {
+ // Handling connecting request
+ case EConnecting:
+ {
+ if ( error == KErrNone )
+ {
+ LOG("Connected to LLCP server");
+ // Updating state
+ iConnState = EConnected;
+ //emit connected signal
+ iSocket.StateChanged(QLlcpSocket::ConnectedState);
+ // Starting listening disconnect event
+ iConnection.WaitForDisconnection( iStatus );
+ SetActive();
+ }
+ else
+ {
+ LOG("!!Failed to Connected to LLCP server");
+ //KErrNotSupported when remote peer has lost from the near field.
+ iConnState = ENotConnected;
+ //emit error signal
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+ break;
+ case EConnected:
+ {
+ //handling disconnect event
+ if ( error == KErrNone )
+ {
+ LOG("Disconnected event received");
+ // Updating state
+ iConnState = ENotConnected;
+ //emit disconnected signal
+ iSocket.StateChanged(QLlcpSocket::ClosingState);
+ }
+ else
+ {
+ iConnState = ENotConnected;
+ //emit error signal
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+ break;
+ default:
+ {
+ // Do nothing
+ }
+ break;
+ }
+ END
+ }
+void CLlcpConnecterAO::DoCancel()
+ {
+ BEGIN
+ switch ( iConnState )
+ {
+ case EConnecting:
+ {
+ iConnection.ConnectCancel();
+ }
+ break;
+
+ case EConnected:
+ {
+ iConnection.WaitForDisconnectionCancel();
+ }
+ break;
+
+ default:
+ {
+ // Do nothing
+ }
+ break;
+ }
+ END
+ }
+//sender AO implementation
+
+CLlcpSenderAO* CLlcpSenderAO::NewL( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket )
+ {
+ BEGIN
+ CLlcpSenderAO* self = new (ELeave) CLlcpSenderAO( aConnection, aSocket );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ END
+ return self;
+ }
+
+CLlcpSenderAO::CLlcpSenderAO( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket )
+ : CActive( EPriorityStandard ),
+ iConnection( aConnection ),
+ iSocket( aSocket )
+ {
+ }
+/*
+ ConstructL
+*/
+void CLlcpSenderAO::ConstructL()
+ {
+ BEGIN
+ CActiveScheduler::Add( this );
+ END
+ }
+
+/*
+ * Destructor.
+ */
+CLlcpSenderAO::~CLlcpSenderAO()
+ {
+ BEGIN
+ Cancel();
+ iSendBuf0.Close();
+ iSendBuf1.Close();
+ //todo
+ iCurrentSendBuf.Close();
+ END
+ }
+/*
+ * Transfer given data to remote device.
+ */
+TInt CLlcpSenderAO::Send( const TDesC8& aData )
+ {
+ BEGIN
+ TInt error = KErrNone;
+ if (aData.Length() == 0)
+ {
+ END
+ return KErrArgument;
+ }
+ TInt supportedDataLength = iConnection.SupportedDataLength();
+ if (supportedDataLength <= 0)
+ {
+ END
+ return KErrNotReady;
+ }
+ if ( !IsActive() )
+ {
+ // Copying data to internal buffer.
+ iSendBuf0.Zero();
+ iCurrentPos = 0;
+ error = iSendBuf0.ReAlloc( aData.Length() );
+
+ if ( error == KErrNone )
+ {
+ iSendBuf0.Append( aData );
+
+ if (iSendBuf0.Length() > supportedDataLength)
+ {
+ iCurrentSendPtr.Set(iSendBuf0.Ptr(), supportedDataLength);
+ }
+ else
+ {
+ iCurrentSendPtr.Set(iSendBuf0.Ptr(), iSendBuf0.Length());
+ }
+ // Sending data
+ //TODO defect in NFC server
+ iCurrentSendBuf.Close();
+ iCurrentSendBuf.Create(iCurrentSendPtr);
+ iConnection.Transmit( iStatus, iCurrentSendBuf );
+// iConnection.Transmit( iStatus, iCurrentSendPtr );
+ SetActive();
+ iCurrentBuffer = EBuffer0;
+ }
+ }
+ else
+ {
+ if (iCurrentBuffer == EBuffer0)
+ {
+ error = iSendBuf1.ReAlloc( iSendBuf1.Length() + aData.Length() );
+ if (error == KErrNone)
+ {
+ iSendBuf1.Append(aData);
+ }
+ }
+ else
+ {
+ error = iSendBuf0.ReAlloc( iSendBuf0.Length() + aData.Length() );
+ if (error == KErrNone)
+ {
+ iSendBuf0.Append(aData);
+ }
+ }
+ }
+ END
+ return error;
+ }
+
+void CLlcpSenderAO::SendRestDataAndSwitchBuffer(RBuf8& aWorkingBuffer, RBuf8& aNextBuffer)
+ {
+ BEGIN
+ TInt supportedDataLength = iConnection.SupportedDataLength();
+ if (iCurrentPos == aWorkingBuffer.Length())
+ {
+ LOG("Current working buffer write finished");
+
+ aWorkingBuffer.Zero();
+ if(aNextBuffer.Length() > 0)
+ {
+
+ if (&aNextBuffer == &iSendBuf0)
+ {
+ iCurrentBuffer = EBuffer0;
+ LOG("Start switch to buffer 0");
+ }
+ else
+ {
+ iCurrentBuffer = EBuffer1;
+ LOG("Start switch to buffer 1");
+ }
+
+ iCurrentPos = 0;
+
+ if (supportedDataLength > 0)
+ {
+ if (aNextBuffer.Length() > supportedDataLength)
+ {
+ iCurrentSendPtr.Set(aNextBuffer.Ptr(), supportedDataLength);
+ }
+ else
+ {
+ iCurrentSendPtr.Set(aNextBuffer.Ptr(), aNextBuffer.Length());
+ }
+ //TODO
+ iCurrentSendBuf.Close();
+ iCurrentSendBuf.Create(iCurrentSendPtr);
+ iConnection.Transmit( iStatus, iCurrentSendBuf );
+// iConnection.Transmit( iStatus, iCurrentSendPtr );
+ SetActive();
+ }
+ else
+ {
+ LOG("SupportedDataLength is invalid, value="<<supportedDataLength);
+ iSendBuf0.Zero();
+ iSendBuf1.Zero();
+ iCurrentBuffer = EBuffer0;
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+ }
+ else //means current working buffer still have data need to be sent
+ {
+ LOG("Current working buffer still has data need to be sent");
+ if (supportedDataLength > 0)
+ {
+ if (aWorkingBuffer.Length() - iCurrentPos > supportedDataLength)
+ {
+ iCurrentSendPtr.Set(aWorkingBuffer.Ptr() + iCurrentPos, supportedDataLength);
+ }
+ else
+ {
+ iCurrentSendPtr.Set(aWorkingBuffer.Ptr() + iCurrentPos, aWorkingBuffer.Length() - iCurrentPos);
+ }
+ // Sending data
+ //TODO
+ iCurrentSendBuf.Close();
+ iCurrentSendBuf.Create(iCurrentSendPtr);
+ iConnection.Transmit( iStatus, iCurrentSendBuf );
+
+// iConnection.Transmit( iStatus, iCurrentSendPtr );
+ SetActive();
+ }
+ else
+ {
+ LOG("SupportedDataLength is invalid, value="<<supportedDataLength);
+ iSendBuf0.Zero();
+ iSendBuf1.Zero();
+ iCurrentBuffer = EBuffer0;
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+ END
+ }
+void CLlcpSenderAO::RunL()
+ {
+ BEGIN
+ TInt error = iStatus.Int();
+ if ( error == KErrNone )
+ {
+ TInt bytesWritten = iCurrentSendPtr.Length();
+
+ iCurrentPos += iCurrentSendPtr.Length();
+ if (iCurrentBuffer == EBuffer0)
+ {
+ SendRestDataAndSwitchBuffer(iSendBuf0, iSendBuf1);
+ }//if (iCurrentBuffer == EBuffer0)
+ else //current working buffer is buffer1
+ {
+ SendRestDataAndSwitchBuffer(iSendBuf1, iSendBuf0);
+ }
+ //emit BytesWritten signal
+ iSocket.BytesWritten(bytesWritten);
+ }//if ( error == KErrNone )
+ else
+ {
+ LOG("iStatus.Int() = "<<error);
+ iSendBuf0.Zero();
+ iSendBuf1.Zero();
+ iCurrentBuffer = EBuffer0;
+ //emit error() signal
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ END
+ }
+void CLlcpSenderAO::DoCancel()
+ {
+ BEGIN
+ iConnection.TransmitCancel();
+ END
+ }
+//receiver implementation
+CLlcpReceiverAO* CLlcpReceiverAO::NewL( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket )
+ {
+ BEGIN
+ CLlcpReceiverAO* self = new (ELeave) CLlcpReceiverAO( aConnection, aSocket );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ END
+ return self;
+ }
+
+CLlcpReceiverAO::CLlcpReceiverAO( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket )
+ : CActive( EPriorityStandard ),
+ iConnection( aConnection ),
+ iSocket( aSocket )
+ {
+ }
+/*
+ ConstructL
+*/
+void CLlcpReceiverAO::ConstructL()
+ {
+ BEGIN
+ CActiveScheduler::Add( this );
+ END
+ }
+
+/*
+ * Destructor.
+ */
+CLlcpReceiverAO::~CLlcpReceiverAO()
+ {
+ BEGIN
+ Cancel();
+ iReceiveBuf.Close();
+ END
+ }
+
+TInt CLlcpReceiverAO::StartReceiveDatagram()
+ {
+ BEGIN
+ TInt length = 0;
+ TInt error = KErrNone;
+ length = iConnection.SupportedDataLength();
+
+ if ( length > 0 )
+ {
+ iReceiveBuf.Zero();
+ error = iReceiveBuf.ReAlloc( length );
+
+ if ( error == KErrNone )
+ {
+ iConnection.Receive( iStatus, iReceiveBuf );
+ SetActive();
+ }
+ }
+ else
+ {
+ // if length is 0 or negative, LLCP link is destroyed.
+ LOG("Error: length is"<<length);
+ error = KErrNotReady;
+ }
+ END
+ return error;
+ }
+
+void CLlcpReceiverAO::RunL()
+ {
+ BEGIN
+ TInt error = iStatus.Int();
+ if ( error == KErrNone )
+ {
+ //append to buffer
+ HBufC8* buf = NULL;
+ buf = HBufC8::NewLC( iReceiveBuf.Length() );
+ buf->Des().Copy( iReceiveBuf );
+ iSocket.iReceiveBufArray.AppendL( buf );
+ CleanupStack::Pop( buf );
+
+ //emit readyRead() signal
+ iSocket.ReadyRead();
+ //resend the Receive request to NFC server
+ if (StartReceiveDatagram() != KErrNone)
+ {
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ }
+ else if ( error == KErrCancel )
+ {
+ //just omit the KErrCancel
+ LOG(" iStatus = KErrCancel");
+ }
+ else
+ {
+ //emit error() signal
+ iSocket.Error(QLlcpSocket::UnknownSocketError);
+ }
+ END
+ }
+void CLlcpReceiverAO::DoCancel()
+ {
+ BEGIN
+ iConnection.ReceiveCancel();
+ END
+ }
+//EOF
diff --git a/src/nfc/symbian/llcpsockettype2_symbian.h b/src/nfc/symbian/llcpsockettype2_symbian.h
new file mode 100644
index 00000000..e67ea2b9
--- /dev/null
+++ b/src/nfc/symbian/llcpsockettype2_symbian.h
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef LLCPSOCKETTYPE2_SYMBIAN_H_
+#define LLCPSOCKETTYPE2_SYMBIAN_H_
+
+#include <e32base.h>
+#include <nfcserver.h> // RNfcServer
+#include <llcpprovider.h> // CLlcpProvider
+#include <llcpconnorientedtransporter.h> // MLlcpConnOrientedTransporter
+#include <llcpconnorientedlistener.h> // MLlcpConnOrientedListener
+#include <llcplinklistener.h> // MLlcpLinkListener
+#include <qconnectivityglobal.h>
+#include "../qllcpsocket_symbian_p.h"
+#include "../qllcpsocket.h"
+
+/*
+ * FORWARD DECLARATIONS
+ */
+class CLlcpConnecterAO;
+class CLlcpSenderAO;
+class CLlcpReceiverAO;
+class CLlcpTimer;
+/*
+ * CLASS DECLARATION for CLlcpSocketType2 (ConnectOriented Transportation).
+ */
+class CLlcpSocketType2 : public CBase
+{
+public:
+ static CLlcpSocketType2* NewL(QLlcpSocketPrivate* aCallback = NULL);
+
+ static CLlcpSocketType2* NewL(MLlcpConnOrientedTransporter* aTransporter, QLlcpSocketPrivate* aCallback = NULL);
+ ~CLlcpSocketType2();
+
+public:
+ void ConnectToServiceL( const QString &serviceUri);
+ TInt DisconnectFromService();
+
+ TInt StartWriteDatagram(const TDesC8& aData);
+ TBool ReceiveData(TDes8& aData);
+
+ TInt64 BytesAvailable();
+
+ //for qt signals
+ void Error(QLlcpSocket::SocketError aSocketError);
+ void StateChanged(QLlcpSocket::SocketState aSocketState);
+ void ReadyRead();
+ void BytesWritten(qint64 aBytes);
+
+ TBool WaitForReadyRead(TInt aMilliSeconds);
+ TBool WaitForBytesWritten(TInt aMilliSeconds);
+ TBool WaitForConnected(TInt aMilliSeconds);
+
+ void AttachCallbackHandler(QLlcpSocketPrivate* aCallback);
+private:
+ // Constructor
+ explicit CLlcpSocketType2(MLlcpConnOrientedTransporter* aTransporter = NULL,QLlcpSocketPrivate* aCallback = NULL);
+ // Second phase constructor
+ void ConstructL();
+ void ConnectToServiceL( const TDesC8& aServiceName);
+ enum TWaitStatus
+ {
+ ENone,
+ EWaitForReadyRead,
+ EWaitForBytesWritten,
+ EWaitForConnected,
+ EWaitForDisconnected
+ };
+ TBool WaitForOperationReady(TWaitStatus aWaitStatus,TInt aSeconds);
+ void StopWaitNow(TWaitStatus aWaitStatus);
+private:
+ friend class CLlcpReceiverAO;
+ /*
+ * Handle to NFC-server.
+ * Own.
+ */
+ RNfcServer iNfcServer;
+
+ /*
+ * Pointer to CLlcpProvider object.
+ * Own.
+ */
+ CLlcpProvider* iLlcp;
+
+ MLlcpConnOrientedTransporter* iTransporter;
+
+ CLlcpConnecterAO* iConnecter;
+ CLlcpSenderAO* iSender;
+ CLlcpReceiverAO* iReceiver;
+
+ RPointerArray<HBufC8> iReceiveBufArray;
+ TInt iBufferOffset;
+
+ CActiveSchedulerWait * iWait;
+ TWaitStatus iWaitStatus;
+ CLlcpTimer * iTimer;
+
+ QLlcpSocketPrivate* iCallback; // not own
+
+};
+
+class CLlcpConnecterAO : public CActive
+{
+public:
+ static CLlcpConnecterAO* NewL( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket );
+ ~CLlcpConnecterAO();
+
+public:
+ /*
+ * Disonnect with remote peer .
+ */
+ void Disconnect();
+
+ /*
+ * Connect to remote peer as given service uri.
+ */
+ void ConnectL(const TDesC8& aServiceName);
+
+private: // From CActive
+ void RunL();
+ void DoCancel();
+
+private:
+ // Constructor
+ CLlcpConnecterAO( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket );
+ // Second phase constructor
+ void ConstructL();
+
+private:
+ enum TConnectionState
+ {
+ ENotConnected,
+ EConnecting,
+ EConnected
+ };
+ /*
+ Pointer to MLlcpConnOrientedTransporter object.
+ */
+ MLlcpConnOrientedTransporter& iConnection;//Not Own
+ CLlcpSocketType2& iSocket;
+ /*
+ State of LLCP connection object.
+ */
+ TConnectionState iConnState;
+};
+class CLlcpSenderAO : public CActive
+{
+public:
+ static CLlcpSenderAO* NewL( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket );
+ ~CLlcpSenderAO();
+
+public:
+ /*
+ Transfer given data to remote device.
+ */
+ TInt Send( const TDesC8& aData );
+
+private: // From CActive
+ void RunL();
+ void DoCancel();
+
+private:
+ // Constructor
+ CLlcpSenderAO( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket );
+ // Second phase constructor
+ void ConstructL();
+private:
+ void SendRestDataAndSwitchBuffer(RBuf8& aWorkingBuffer, RBuf8& aNextBuffer);
+
+private:
+ /*
+ Pointer to MLlcpConnOrientedTransporter object.
+ */
+ MLlcpConnOrientedTransporter& iConnection; //Not Own
+
+ CLlcpSocketType2& iSocket;
+ enum TSendBuffer
+ {
+ EBuffer0,
+ EBuffer1
+ };
+ /*
+ * Buffered data for sending data.
+ */
+ RBuf8 iSendBuf0;
+ RBuf8 iSendBuf1;
+ TSendBuffer iCurrentBuffer;
+ TPtrC8 iCurrentSendPtr;
+ TInt iCurrentPos;
+ RBuf8 iCurrentSendBuf;
+};
+class CLlcpReceiverAO : public CActive
+{
+public:
+ static CLlcpReceiverAO* NewL( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket );
+ ~CLlcpReceiverAO();
+
+public:
+ /*
+ Receive data from remote device.
+ */
+ TInt StartReceiveDatagram();
+
+private: // From CActive
+ void RunL();
+ void DoCancel();
+
+private:
+ // Constructor
+ CLlcpReceiverAO( MLlcpConnOrientedTransporter& aConnection, CLlcpSocketType2& aSocket );
+ // Second phase constructor
+ void ConstructL();
+private:
+
+ /*
+ * Pointer to MLlcpConnOrientedTransporter object.
+ */
+ MLlcpConnOrientedTransporter& iConnection; //Not Own
+
+ CLlcpSocketType2& iSocket;
+ /*
+ * Buffered data for receiving data.
+ */
+ RBuf8 iReceiveBuf;
+};
+
+#endif /* LLCPSOCKETTYPE2_SYMBIAN_H_ */
diff --git a/src/nfc/symbian/nearfieldmanager_symbian.cpp b/src/nfc/symbian/nearfieldmanager_symbian.cpp
new file mode 100644
index 00000000..c0d485b3
--- /dev/null
+++ b/src/nfc/symbian/nearfieldmanager_symbian.cpp
@@ -0,0 +1,388 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nearfieldmanager_symbian.h"
+#include "nearfieldtargetfactory_symbian.h"
+#include "../qnearfieldmanager_symbian_p.h"
+#include "nearfieldutility_symbian.h"
+
+#include <ndefmessage.h>
+#include "debug.h"
+
+/*
+ \class CNearFieldManager
+ \brief The CNearFieldManager class provides symbian backend implementation to access NFC service.
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+ \internal
+
+ A Symbian implementation class to support symbian NFC backend.
+*/
+
+/*
+ Constructs a CNearFieldManager.
+*/
+void CNearFieldManager::ConstructL()
+ {
+ BEGIN
+ User::LeaveIfError(iServer.Open());
+ END
+ }
+
+/*
+ Start listening all type tags.
+*/
+void CNearFieldManager::StartTargetDetectionL(const QList<QNearFieldTarget::Type> &aTargetTypes)
+ {
+ BEGIN
+ if (aTargetTypes.size() > 0)
+ {
+ if (!iNfcTagDiscovery)
+ {
+ iNfcTagDiscovery = CNfcTagDiscovery::NewL( iServer );
+ User::LeaveIfError(iNfcTagDiscovery->AddTagConnectionListener( *this ));
+ }
+ else
+ {
+ iNfcTagDiscovery->RemoveTagSubscription();
+ }
+
+ if (!iTagSubscription)
+ {
+ iTagSubscription = CNfcTagSubscription::NewL();
+ }
+ else
+ {
+ iTagSubscription->RemoveAllConnectionModes();
+ }
+ for (int i = 0; i < aTargetTypes.size(); ++i)
+ {
+ switch(aTargetTypes[i])
+ {
+ case QNearFieldTarget::NfcTagType1:
+ iTagSubscription->RemoveConnectionMode(TNfcConnectionInfo::ENfcType1);
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcType1 );
+ break;
+ case QNearFieldTarget::NfcTagType2:
+ iTagSubscription->RemoveConnectionMode(TNfcConnectionInfo::ENfcType2);
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcType2 );
+ break;
+ case QNearFieldTarget::NfcTagType3:
+ iTagSubscription->RemoveConnectionMode(TNfcConnectionInfo::ENfcType3);
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcType3 );
+ break;
+ case QNearFieldTarget::NfcTagType4:
+ iTagSubscription->RemoveConnectionMode(TNfcConnectionInfo::ENfc14443P4);
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfc14443P4 );
+ break;
+ case QNearFieldTarget::MifareTag:
+ iTagSubscription->RemoveConnectionMode(TNfcConnectionInfo::ENfcMifareStd);
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcMifareStd );
+ break;
+ case QNearFieldTarget::AnyTarget:
+ iTagSubscription->RemoveAllConnectionModes();
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcType1 );
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcType2 );
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcType3 );
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfc14443P4 );
+ iTagSubscription->AddConnectionModeL( TNfcConnectionInfo::ENfcMifareStd );
+ if (!iLlcpProvider)
+ {
+ //create LLCP provider api
+ iLlcpProvider = CLlcpProvider::NewL( iServer );
+ iLlcpProvider->AddLlcpLinkListenerL( *this );
+ }
+ break;
+ case QNearFieldTarget::ProprietaryTag:
+ //No conterpart in symbian api
+ break;
+ case QNearFieldTarget::NfcForumDevice:
+ if (!iLlcpProvider)
+ {
+ //create LLCP provider api
+ iLlcpProvider = CLlcpProvider::NewL( iServer );
+ iLlcpProvider->AddLlcpLinkListenerL( *this );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ iNfcTagDiscovery->AddTagSubscriptionL( *iTagSubscription );
+ END
+ }
+
+/*
+ Stop listening all type tags.
+*/
+void CNearFieldManager::stopTargetDetection()
+ {
+ BEGIN
+ if (iNfcTagDiscovery)
+ {
+ iNfcTagDiscovery->RemoveTagConnectionListener();
+ iNfcTagDiscovery->RemoveTagSubscription();
+
+ if (iTagSubscription)
+ {
+ delete iTagSubscription;
+ iTagSubscription = NULL;
+ }
+ delete iNfcTagDiscovery;
+ iNfcTagDiscovery = NULL;
+ }
+ if (iLlcpProvider)
+ {
+ iLlcpProvider->RemoveLlcpLinkListener();
+ delete iLlcpProvider;
+ iLlcpProvider = NULL;
+ }
+
+ END
+ }
+
+CNdefRecord::TNdefRecordTnf CNearFieldManager::QTnf2CTnf(const QNdefRecord::TypeNameFormat aQTnf)
+ {
+ CNdefRecord::TNdefRecordTnf ret = CNdefRecord::EEmpty;
+ switch(aQTnf)
+ {
+ case QNdefRecord::Empty:
+ break;
+ case QNdefRecord::NfcRtd:
+ ret = CNdefRecord::ENfcWellKnown;
+ break;
+ case QNdefRecord::Mime:
+ ret = CNdefRecord::EMime;
+ break;
+ case QNdefRecord::Uri:
+ ret = CNdefRecord::EUri;
+ break;
+ case QNdefRecord::ExternalRtd:
+ ret = CNdefRecord::ENfcExternal;
+ break;
+ case QNdefRecord::Unknown:
+ ret = CNdefRecord::EUnknown;
+ break;
+ default:
+ break;
+ }
+ return ret;
+ }
+
+/*
+ Register interested TNF NDEF message to NFC server.
+*/
+TInt CNearFieldManager::AddNdefSubscription( const QNdefRecord::TypeNameFormat aTnf,
+ const QByteArray& aType )
+ {
+ BEGIN
+ TInt err = KErrNone;
+ if ( !iNdefDiscovery )
+ {
+ TRAP(err, iNdefDiscovery = CNdefDiscovery::NewL( iServer ));
+ if (err != KErrNone)
+ {
+ END
+ return err;
+ }
+ err = iNdefDiscovery->AddNdefMessageListener( *this );
+ if (err != KErrNone)
+ {
+ END
+ return err;
+ }
+
+ }
+ TPtrC8 type(QNFCNdefUtility::QByteArray2TPtrC8(aType));
+ err = iNdefDiscovery->AddNdefSubscription( QTnf2CTnf(aTnf), type );
+ END
+ return err;
+ }
+
+/*
+ Unregister interested TNF NDEF message to NFC server.
+*/
+void CNearFieldManager::RemoveNdefSubscription( const QNdefRecord::TypeNameFormat aTnf,
+ const QByteArray& aType )
+ {
+ BEGIN
+ if ( iNdefDiscovery )
+ {
+ TPtrC8 type(QNFCNdefUtility::QByteArray2TPtrC8(aType));
+ iNdefDiscovery->RemoveNdefSubscription( QTnf2CTnf(aTnf), type );
+ }
+ END
+ }
+
+/*
+ Callback function when the tag found by NFC symbain services.
+*/
+void CNearFieldManager::TagDetected( MNfcTag* aNfcTag )
+ {
+ BEGIN
+ if (aNfcTag)
+ {
+ QNearFieldTarget* tag = TNearFieldTargetFactory::CreateTargetL(aNfcTag, iServer, &iCallback);
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error, iCallback.targetFound(tag));
+ Q_UNUSED(error);//just skip the error
+ }
+ END
+ }
+
+/*
+ Callback function when the tag lost event found by NFC symbain services.
+*/
+void CNearFieldManager::TagLost()
+ {
+ BEGIN
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error, iCallback.targetDisconnected());//just skip the error
+ Q_UNUSED(error);//just skip the error
+ END
+ }
+
+/*
+ Callback function when the LLCP peer found by NFC symbain services.
+*/
+void CNearFieldManager::LlcpRemoteFound()
+ {
+ BEGIN
+ TInt error = KErrNone;
+ QNearFieldTarget* tag = NULL;
+ TRAP(error, tag = TNearFieldTargetFactory::CreateTargetL(NULL, iServer, &iCallback));
+ if (error == KErrNone)
+ {
+ QT_TRYCATCH_ERROR(error, iCallback.targetFound(tag) );
+ Q_UNUSED(error);//just skip the error
+ }
+ END
+ }
+
+/*
+ Callback function when the LLCP peer lost event found by NFC symbain services.
+*/
+void CNearFieldManager::LlcpRemoteLost()
+ {
+ BEGIN
+ TInt error = KErrNone;
+ QT_TRYCATCH_ERROR(error, iCallback.targetDisconnected());
+ Q_UNUSED(error);//just skip the error
+ END
+ }
+
+/*
+ Callback function when the registerd NDEF message found by NFC symbain services.
+*/
+void CNearFieldManager::MessageDetected( CNdefMessage* aMessage )
+ {
+ BEGIN
+ if ( aMessage )
+ {
+ TInt error = KErrNone;
+ QNdefMessage msg;
+ TRAP(error, msg = QNFCNdefUtility::CNdefMsg2QNdefMsgL( *aMessage));
+ if (error == KErrNone)
+ {
+ QT_TRYCATCH_ERROR(error, iCallback.invokeNdefMessageHandler(msg));
+ Q_UNUSED(error);//just skip the error
+ }
+ delete aMessage;
+ }
+ END
+ }
+
+/*
+ New a CNearFieldManager instance.
+*/
+CNearFieldManager::CNearFieldManager( QNearFieldManagerPrivateImpl& aCallback)
+ : iCallback(aCallback)
+ {
+ }
+
+/*
+ Create a new instance of this class.
+*/
+CNearFieldManager* CNearFieldManager::NewL( QNearFieldManagerPrivateImpl& aCallback)
+ {
+ BEGIN
+ CNearFieldManager* self = new (ELeave) CNearFieldManager(aCallback);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ END
+ return self;
+ }
+
+/*
+ Destructor.
+*/
+CNearFieldManager::~CNearFieldManager()
+ {
+ BEGIN
+ if ( iNfcTagDiscovery )
+ {
+ iNfcTagDiscovery->RemoveTagConnectionListener();
+ iNfcTagDiscovery->RemoveTagSubscription();
+ }
+
+ delete iTagSubscription;
+ delete iNfcTagDiscovery;
+
+ if (iLlcpProvider)
+ {
+ iLlcpProvider->RemoveLlcpLinkListener();
+ }
+ delete iLlcpProvider;
+
+ if (iNdefDiscovery)
+ {
+ iNdefDiscovery->RemoveAllNdefSubscription();
+ }
+ delete iNdefDiscovery;
+
+ iServer.Close();
+ END
+ }
+//EOF
diff --git a/src/nfc/symbian/nearfieldmanager_symbian.h b/src/nfc/symbian/nearfieldmanager_symbian.h
new file mode 100644
index 00000000..82e05436
--- /dev/null
+++ b/src/nfc/symbian/nearfieldmanager_symbian.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDMANAGER_SYMBIAN_H_
+#define QNEARFIELDMANAGER_SYMBIAN_H_
+
+#include <nfcserver.h>
+#include <nfctag.h>
+#include <nfctagsubscription.h>
+#include <nfcconnection.h>
+#include <nfctype2connection.h>
+
+#include <nfctagdiscovery.h>
+#include <nfctagconnectionlistener.h>
+#include <nfcconnectioninfo.h>
+#include <llcpprovider.h> // CLlcpProvider
+#include <llcplinklistener.h> // MLlcpLinkListener
+
+#include <ndefmessagelistener.h>
+#include <ndefdiscovery.h>
+
+#include "../qndefrecord.h"
+#include <QList>
+#include "../qnearfieldtarget.h"
+
+class QNearFieldManagerPrivateImpl;
+
+class CNearFieldManager : public CBase,
+ public MNfcTagConnectionListener,
+ public MLlcpLinkListener,
+ public MNdefMessageListener
+ {
+public:
+
+ static CNearFieldManager* NewL( QNearFieldManagerPrivateImpl& aCallback);
+ virtual ~CNearFieldManager();
+
+ void StartTargetDetectionL(const QList<QNearFieldTarget::Type> &aTargetTypes);
+ void stopTargetDetection();
+ //for registerNdefMessageHandler ... api
+ TInt AddNdefSubscription( const QNdefRecord::TypeNameFormat aTnf,
+ const QByteArray& aType );
+ void RemoveNdefSubscription( const QNdefRecord::TypeNameFormat aTnf,
+ const QByteArray& aType );
+
+public: // From MNfcTagConnectionListener
+
+ void TagDetected( MNfcTag* aNfcTag );
+ void TagLost();
+
+public: // From MLlcpLinkListener
+
+ void LlcpRemoteFound();
+ void LlcpRemoteLost();
+
+public: // From MNdefMessageListener
+
+ void MessageDetected( CNdefMessage* aMessage );
+
+private:
+
+ CNearFieldManager( QNearFieldManagerPrivateImpl& aCallback);
+ void ConstructL();
+ CNdefRecord::TNdefRecordTnf QTnf2CTnf(const QNdefRecord::TypeNameFormat aQTnf);
+ //own
+ RNfcServer iServer;
+ //for Tag discovery
+ CNfcTagDiscovery* iNfcTagDiscovery;
+ CNfcTagSubscription* iTagSubscription;
+ //for LLCP discovery
+ CLlcpProvider* iLlcpProvider;
+ //for NDEF discovery
+ CNdefDiscovery* iNdefDiscovery;
+ //not own
+ QNearFieldManagerPrivateImpl& iCallback;
+ };
+#endif /* QNEARFIELDMANAGER_SYMBIAN_H_ */
diff --git a/src/nfc/symbian/nearfieldndeftarget_symbian.cpp b/src/nfc/symbian/nearfieldndeftarget_symbian.cpp
new file mode 100644
index 00000000..0167462a
--- /dev/null
+++ b/src/nfc/symbian/nearfieldndeftarget_symbian.cpp
@@ -0,0 +1,315 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+#include <nfctype1connection.h>
+#include <nfctype2connection.h>
+#include <nfctype3connection.h>
+#include <iso14443connection.h>
+#include <ndefconnection.h>
+#include <nfctag.h>
+#include <qglobal.h>
+#include "nearfieldtag_symbian.h"
+#include "nearfieldndeftarget_symbian.h"
+#include "nearfieldtagndefoperationcallback_symbian.h"
+#include "debug.h"
+
+CNearFieldNdefTarget::CNearFieldNdefTarget(MNfcTag * aNfcTag, RNfcServer& aNfcServer) : iNfcTag(aNfcTag),
+ iNfcServer(aNfcServer),
+ iCurrentOperation(ENull)
+ {
+ }
+
+CNearFieldNdefTarget* CNearFieldNdefTarget::NewLC(MNfcTag * aNfcTag, RNfcServer& aNfcServer)
+ {
+ CNearFieldNdefTarget* self = new (ELeave) CNearFieldNdefTarget(aNfcTag, aNfcServer);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+void CNearFieldNdefTarget::ConstructL()
+ {
+ iNdefConnection = CNdefConnection::NewL(iNfcServer, *this);
+ }
+
+void CNearFieldNdefTarget::SetRealTarget(CNearFieldTag * aRealTarget)
+ {
+ iTagConnection = aRealTarget;
+ }
+
+CNearFieldNdefTarget::~CNearFieldNdefTarget()
+ {
+ BEGIN
+ // when connection is closed, cancel for each specific connection will be done.
+ if (iNdefConnection)
+ {
+ if (iNdefConnection->IsActivated())
+ {
+ CloseConnection();
+ }
+ delete iNdefConnection;
+ }
+
+ // when Ndef target has a tag connection, iNfcTag ownership
+ // will transfer to tag connection.
+ if (iTagConnection)
+ {
+ delete iTagConnection;
+ }
+ else
+ {
+ delete iNfcTag;
+ }
+ END
+ }
+
+void CNearFieldNdefTarget::Cancel()
+ {
+ BEGIN
+ if (ERead == iCurrentOperation)
+ {
+ iNdefConnection->CancelRead();
+ }
+ else if (EWrite == iCurrentOperation)
+ {
+ iNdefConnection->CancelWrite();
+ }
+
+ iCurrentOperation = ENull;
+ END
+ }
+
+CNearFieldTag * CNearFieldNdefTarget::CastToTag()
+ {
+ BEGIN
+ if (IsConnectionOpened())
+ {
+ LOG("Ndef connection will be closed");
+ CloseConnection();
+ }
+ END
+ return iTagConnection ? iTagConnection->CastToTag() : reinterpret_cast<CNearFieldTag *>(0);
+ }
+
+CNearFieldNdefTarget * CNearFieldNdefTarget::CastToNdefTarget()
+ {
+ BEGIN
+ TInt error = KErrNone;
+ if (iTagConnection)
+ {
+ LOG("Check if Tag Connection is opened");
+ if (iTagConnection->IsConnectionOpened())
+ {
+ LOG("Close tag connection");
+ iTagConnection->CloseConnection();
+ }
+ }
+
+ if (!IsConnectionOpened())
+ {
+ LOG("Open ndef connection")
+ error = OpenConnection();
+ LOG("error code is"<<error);
+ }
+ END
+ return (error == KErrNone) ? const_cast<CNearFieldNdefTarget *>(this)
+ : reinterpret_cast<CNearFieldNdefTarget *>(0);
+ }
+
+TInt CNearFieldNdefTarget::OpenConnection()
+ {
+ BEGIN
+ END
+ return iNfcTag->OpenConnection(*iNdefConnection);
+ }
+
+void CNearFieldNdefTarget::CloseConnection()
+ {
+ BEGIN
+ END
+ return iNfcTag->CloseConnection(*iNdefConnection);
+ }
+
+TBool CNearFieldNdefTarget::IsConnectionOpened()
+ {
+ BEGIN
+ TBool result = iNdefConnection->IsActivated();
+ LOG(result);
+ END
+ return result;
+ }
+
+const TDesC8& CNearFieldNdefTarget::Uid() const
+ {
+ BEGIN
+ END
+ return iNfcTag->Uid();
+ }
+
+void CNearFieldNdefTarget::ReadComplete( CNdefMessage* aMessage )
+ {
+ BEGIN
+ if (iCallback)
+ {
+ TInt err = KErrNone;
+ if (iMessages)
+ {
+ err = iMessages->Append(aMessage);
+ LOG("append message, err = "<<err);
+ }
+
+ TInt errIgnore = KErrNone;
+ QT_TRYCATCH_ERROR(errIgnore, iCallback->ReadComplete(err, iMessages));
+ //TODO: consider it carefully
+ //iMessages = 0;
+ LOG("callback error is "<<errIgnore);
+ }
+ iCurrentOperation = ENull;
+ LOG(iCurrentOperation);
+ END
+ }
+
+void CNearFieldNdefTarget::WriteComplete()
+ {
+ BEGIN
+ if (iCallback)
+ {
+ TInt errIgnore = KErrNone;
+ QT_TRYCATCH_ERROR(errIgnore, iCallback->WriteComplete(KErrNone));
+ LOG("callback error is "<<errIgnore);
+ }
+ iCurrentOperation = ENull;
+ LOG(iCurrentOperation);
+ END
+ }
+
+void CNearFieldNdefTarget::HandleError( TInt aError )
+ {
+ BEGIN
+ if (iCallback)
+ {
+ LOG(iCurrentOperation);
+
+ if (ERead == iCurrentOperation)
+ {
+ iCallback->ReadComplete(aError, iMessages);
+ }
+ else if (EWrite == iCurrentOperation)
+ {
+ iCallback->WriteComplete(aError);
+ }
+ //TODO: consider it carefully
+ //iMessages = 0;
+ }
+ iCurrentOperation = ENull;
+ END
+ }
+
+TInt CNearFieldNdefTarget::ndefMessages(RPointerArray<CNdefMessage>& aMessages)
+ {
+ BEGIN
+ TInt error = KErrNone;
+ LOG("iCurrentOperation = "<<iCurrentOperation);
+ if (iCurrentOperation != ENull)
+ {
+ error = KErrInUse;
+ }
+ else
+ {
+ if (!IsConnectionOpened())
+ {
+ error = OpenConnection();
+ LOG("Open connection, err = "<<error);
+ }
+ if (KErrNone == error)
+ {
+ LOG("begin to read message");
+ iMessages = &aMessages;
+ error = iNdefConnection->ReadMessage();
+ LOG("read message err = "<<error);
+ iCurrentOperation = (KErrNone == error) ? ERead : ENull;
+ }
+ }
+ END
+ return error;
+ }
+
+TInt CNearFieldNdefTarget::setNdefMessages(const RPointerArray<CNdefMessage>& aMessages)
+ {
+ BEGIN
+ TInt error = KErrNone;
+ CNdefMessage * message;
+ LOG("iCurrentOperation = "<<iCurrentOperation);
+ if (iCurrentOperation != ENull)
+ {
+ error = KErrInUse;
+ }
+ else
+ {
+ if (aMessages.Count() > 0)
+ {
+ LOG("message count > 0");
+ // current only support single ndef message
+ message = aMessages[0];
+ if (!IsConnectionOpened())
+ {
+ error = OpenConnection();
+ LOG("Open connection, err = "<<error);
+ }
+ if (KErrNone == error)
+ {
+ LOG("begin to write message");
+ error = iNdefConnection->WriteMessage(*message);
+ LOG("write message err = "<<error);
+ iCurrentOperation = (KErrNone == error) ? EWrite : ENull;
+ }
+ }
+ }
+ END
+ return error;
+ }
+
+void CNearFieldNdefTarget::SetNdefOperationCallback(MNearFieldNdefOperationCallback * const aCallback)
+ {
+ BEGIN
+ iCallback = aCallback;
+ END
+ }
+
diff --git a/src/nfc/symbian/nearfieldndeftarget_symbian.h b/src/nfc/symbian/nearfieldndeftarget_symbian.h
new file mode 100644
index 00000000..485e2516
--- /dev/null
+++ b/src/nfc/symbian/nearfieldndeftarget_symbian.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef NEARFIELDNDEFTARGET_H
+#define NEARFIELDNDEFTARGET_H
+
+#include <e32base.h>
+#include <nfcserver.h>
+#include <ndefconnection.h>
+#include <e32cmn.h>
+#include <ndefhandler.h>
+
+#include "debug.h"
+
+class CNearFieldTag;
+class CNdefMessage;
+
+class CNdefConnection;
+class MNfcTag;
+
+class MNearFieldNdefOperationCallback;
+
+class CNearFieldNdefTarget : public CBase,
+ public MNdefHandler
+ {
+ enum TOperation
+ {
+ ENull,
+ ERead,
+ EWrite
+ };
+public:
+ // Cancel and destroy
+ ~CNearFieldNdefTarget();
+
+ // Two-phased constructor.
+ static CNearFieldNdefTarget* NewLC(MNfcTag * aNfcTag, RNfcServer& aNfcServer);
+public: // New functions
+ void SetRealTarget(CNearFieldTag * aRealTarget);
+
+ // NdefAccess
+ TInt ndefMessages(RPointerArray<CNdefMessage>& aMessages);
+ TInt setNdefMessages(const RPointerArray<CNdefMessage>& aMessages);
+ void Cancel();
+
+public:
+ CNearFieldTag * CastToTag();
+ CNearFieldNdefTarget * CastToNdefTarget();
+
+ TInt OpenConnection();
+ void CloseConnection();
+ TBool IsConnectionOpened();
+ const TDesC8& Uid() const;
+ void SetNdefOperationCallback(MNearFieldNdefOperationCallback * const aCallback);
+
+private:
+ // C++ constructor
+ CNearFieldNdefTarget(MNfcTag * aNfcTag, RNfcServer& aNfcServer);
+
+ // Second-phase constructor
+ void ConstructL();
+
+private: // From MNdefHandler
+ void ReadComplete( CNdefRecord* /*aRecord*/, CNdefRecord::TNdefMessagePart /*aPart*/ ){}
+ void ReadComplete( CNdefMessage* aMessage );
+ void ReadComplete( const RPointerArray<CNdefMessage>& /*aMessages*/ ){}
+ void WriteComplete();
+ void HandleError( TInt aError );
+
+private:
+ // own
+ CNearFieldTag * iTagConnection;
+ CNdefConnection * iNdefConnection;
+ // own
+ MNfcTag * iNfcTag;
+
+ RNfcServer& iNfcServer;
+
+ TOperation iCurrentOperation;
+
+ // Not own
+ MNearFieldNdefOperationCallback * iCallback;
+ RPointerArray<CNdefMessage> * iMessages;
+ };
+
+#endif // NEARFIELDNDEFTARGET_H
diff --git a/src/nfc/symbian/nearfieldtag_symbian.cpp b/src/nfc/symbian/nearfieldtag_symbian.cpp
new file mode 100644
index 00000000..e6f9dbbe
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtag_symbian.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <nfctag.h>
+#include <qglobal.h>
+#include <nfcconnection.h>
+#include "nearfieldtag_symbian.h"
+#include "nearfieldtagoperationcallback_symbian.h"
+#include "debug.h"
+/*
+ \class CNearFieldTag
+ \brief The CNearFieldTag class provides ways to access tag
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \internal
+ \since 5.0
+*/
+
+CNearFieldTag::CNearFieldTag(MNfcTag * aNfcTag, RNfcServer& aNfcServer) : CActive(EPriorityStandard),
+ iNfcTag(aNfcTag),
+ iNfcServer(aNfcServer)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CNearFieldTag* CNearFieldTag::NewLC(MNfcTag * aNfcTag, RNfcServer& aNfcServer)
+ {
+ CNearFieldTag* self = new (ELeave) CNearFieldTag(aNfcTag, aNfcServer);
+ CleanupStack::PushL(self);
+ return self;
+ }
+
+CNearFieldTag::~CNearFieldTag()
+ {
+ Cancel();
+ if (iTagConnection)
+ {
+ if(iTagConnection->IsActivated())
+ {
+ CloseConnection();
+ }
+ delete iTagConnection;
+ }
+
+ delete iNfcTag;
+ }
+
+CNearFieldTag * CNearFieldTag::CastToTag()
+ {
+ BEGIN
+ TInt error = KErrNone;
+
+ if (!IsConnectionOpened())
+ {
+ error = OpenConnection();
+ LOG("open connection, error is "<<error);
+ }
+ END
+ return (error == KErrNone) ? const_cast<CNearFieldTag *>(this)
+ : reinterpret_cast<CNearFieldTag *>(0);
+ }
+
+TInt CNearFieldTag::OpenConnection()
+ {
+ BEGIN
+ TInt error = iNfcTag->OpenConnection(*iTagConnection);
+ LOG(error);
+ END
+ return error;
+ }
+
+void CNearFieldTag::CloseConnection()
+ {
+ BEGIN
+ iNfcTag->CloseConnection(*iTagConnection);
+ END
+ }
+
+TBool CNearFieldTag::IsConnectionOpened()
+ {
+ BEGIN
+ LOG((int)iTagConnection);
+ LOG("check if connection is opened");
+ TBool result = iTagConnection->IsActivated();
+ LOG("result is "<<result);
+ END
+ return result;
+ }
+
+TInt CNearFieldTag::RawModeAccess(const TDesC8& aCommand, TDes8& aResponse, TTimeIntervalMicroSeconds32& aTimeout)
+ {
+ BEGIN
+ TInt error = KErrInUse;
+ if (!IsActive())
+ {
+ LOG("AO is not active");
+ // No ongoing request
+ if (IsConnectionOpened())
+ {
+ LOG("Connection is open");
+ error = KErrNone;
+ iTagConnection->RawModeAccess(iStatus, aCommand, aResponse, aTimeout);
+ SetActive();
+ }
+ }
+ END
+ return error;
+ }
+
+void CNearFieldTag::DoCancel()
+ {
+ BEGIN
+ iTagConnection->CancelRawModeAccess();
+ if (iCallback)
+ {
+ LOG("call back command complete with KErrCancel");
+ TInt err;
+ QT_TRYCATCH_ERROR(err, iCallback->CommandComplete(KErrCancel));
+ Q_UNUSED(err);
+ }
+ END
+ }
+
+void CNearFieldTag::RunL()
+ {
+ BEGIN
+ if (iCallback)
+ {
+ LOG("call back command complete with error"<<iStatus.Int());
+ TInt err;
+ QT_TRYCATCH_ERROR(err, iCallback->CommandComplete(iStatus.Int()));
+ Q_UNUSED(err);
+ }
+ END
+ }
+
+void CNearFieldTag::SetTagOperationCallback(MNearFieldTagOperationCallback * const aCallback)
+ {
+ BEGIN
+ iCallback = aCallback;
+ END
+ }
diff --git a/src/nfc/symbian/nearfieldtag_symbian.h b/src/nfc/symbian/nearfieldtag_symbian.h
new file mode 100644
index 00000000..5b59f05a
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtag_symbian.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef NEARFIELDTAG_SYMBIAN_H
+#define NEARFIELDTAG_SYMBIAN_H
+#include <nfcserver.h>
+#include <e32base.h>
+#include <iso14443connection.h>
+
+class MNfcTag;
+class MNfcConnection;
+class MNearFieldTagOperationCallback;
+
+
+class CNearFieldTag : public CActive
+ {
+public:
+ // Cancel and destroy
+ ~CNearFieldTag();
+
+ // Two-phased constructor.
+ static CNearFieldTag* NewLC(MNfcTag * aNfcTag, RNfcServer& aNfcServer);
+
+public:
+ CNearFieldTag * CastToTag();
+ void SetConnection(MNfcConnection * aTagConnection) { iTagConnection = aTagConnection; }
+
+ TInt OpenConnection();
+ void CloseConnection();
+ TBool IsConnectionOpened();
+
+ TInt RawModeAccess(const TDesC8& aCommand, TDes8& aResponse, TTimeIntervalMicroSeconds32& aTimeout);
+
+ MNfcConnection * TagConnection() { return iTagConnection;}
+
+ void SetTagOperationCallback(MNearFieldTagOperationCallback * const aCallback);
+
+private:
+ // C++ constructor
+ CNearFieldTag(MNfcTag * aNfcTag, RNfcServer& aNfcServer);
+
+private:
+ void RunL();
+ void DoCancel();
+
+private:
+ // own
+ MNfcConnection * iTagConnection;
+ MNfcTag * iNfcTag;
+ RNfcServer& iNfcServer;
+ // Not own
+ MNearFieldTagOperationCallback * iCallback;
+ TBool iIsTag4;
+ };
+
+#endif // NEARFIELDTAG_SYMBIAN_H
diff --git a/src/nfc/symbian/nearfieldtagasyncrequest_symbian.cpp b/src/nfc/symbian/nearfieldtagasyncrequest_symbian.cpp
new file mode 100644
index 00000000..48dde301
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagasyncrequest_symbian.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+#include "nearfieldtagasyncrequest_symbian.h"
+#include "nearfieldutility_symbian.h"
+#include "nearfieldtagimplcommon_symbian.h"
+#include <e32std.h>
+#include "debug.h"
+
+TInt MNearFieldTagAsyncRequest::TimeoutCallback(TAny * aObj)
+{
+ BEGIN
+ MNearFieldTagAsyncRequest * obj = static_cast<MNearFieldTagAsyncRequest *>(aObj);
+ obj->ProcessTimeout();
+ END
+ return KErrNone;
+}
+
+MNearFieldTagAsyncRequest::MNearFieldTagAsyncRequest(QNearFieldTagImplCommon& aOperator) : iOperator(aOperator)
+{
+ iWait = 0;
+ iTimer = 0;
+ iRequestIssued = EFalse;
+ iCurrentRequestResult = 0;
+ iSendSignal = true;
+ iRequestResult = 0;
+}
+
+MNearFieldTagAsyncRequest::~MNearFieldTagAsyncRequest()
+{
+ BEGIN
+ if (iTimer)
+ {
+ LOG("delete timer");
+ delete iTimer;
+ iTimer = 0;
+ }
+
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ iWait->AsyncStop();
+ }
+ LOG("delete waiter");
+ delete iWait;
+ }
+ END
+}
+
+void MNearFieldTagAsyncRequest::SetRequestId(QNearFieldTarget::RequestId aId)
+{
+ BEGIN
+ iId = aId;
+ END
+}
+
+QNearFieldTarget::RequestId MNearFieldTagAsyncRequest::RequestID()
+{
+ BEGIN
+ END
+ return iId;
+}
+
+bool MNearFieldTagAsyncRequest::WaitRequestCompleted(int aMsecs)
+{
+ BEGIN
+ volatile bool result = false;
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ LOG("waiter has already started");
+ // the request is already waited, return false.
+ return false;
+ }
+ }
+ else
+ {
+ LOG("new a new waiter");
+ iWait = new(ELeave) CActiveSchedulerWait();
+ iCurrentRequestResult = &result;
+ }
+
+ if (iTimer)
+ {
+ LOG("cancel previous timer");
+ iTimer->Cancel();
+ }
+ else
+ {
+ LOG("create a new timer");
+ iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+ }
+
+ iMsecs = aMsecs * 1000;
+ if (iRequestIssued)
+ {
+ // timer should be started when request is issued.
+ LOG("Start timer");
+ TCallBack callback(MNearFieldTagAsyncRequest::TimeoutCallback, this);
+ iTimer->Start(iMsecs, iMsecs, callback);
+ }
+ LOG("Start waiter");
+ iWait->Start();
+ LOG("Waiting completed, "<<result);
+ END
+ return result;
+}
+
+int MNearFieldTagAsyncRequest::WaitRequestCompletedNoSignal(int aMsecs)
+{
+ BEGIN
+ volatile int result = KErrNone;
+ iSendSignal = false;
+ iRequestResult = &result;
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ LOG("waiter has already started");
+ // the request is already waited, return false.
+ return KErrInUse;
+ }
+ }
+ else
+ {
+ LOG("new a new waiter");
+ iWait = new(ELeave) CActiveSchedulerWait();
+ iRequestResult = &result;
+ }
+
+ if (iTimer)
+ {
+ LOG("cancel previous timer");
+ iTimer->Cancel();
+ }
+ else
+ {
+ LOG("create a new timer");
+ iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+ }
+
+ iMsecs = aMsecs * 1000;
+ if (iRequestIssued)
+ {
+ // timer should be started when request is issued.
+ LOG("Start timer");
+ TCallBack callback(MNearFieldTagAsyncRequest::TimeoutCallback, this);
+ iTimer->Start(iMsecs, iMsecs, callback);
+ }
+ LOG("Start waiter");
+ iWait->Start();
+ LOG("Waiting completed, "<<result);
+ END
+ return result;
+}
+
+
+void MNearFieldTagAsyncRequest::ProcessResponse(TInt aError)
+{
+ BEGIN
+ LOG("Error is "<<aError);
+
+ iOperator.IssueNextRequest(iId);
+
+ HandleResponse(aError);
+
+ if (iWait)
+ {
+ ProcessWaitRequestCompleted(aError);
+ }
+ else
+ {
+ ProcessEmitSignal(aError);
+ }
+
+ LOG("remove the request from queue");
+ iOperator.RemoveRequestFromQueue(iId);
+ LOG("delete the request");
+ iRequestIssued = EFalse;
+ delete this;
+ END
+}
+
+void MNearFieldTagAsyncRequest::ProcessWaitRequestCompleted(TInt aError)
+{
+ BEGIN
+ if (iSendSignal)
+ {
+ if (iCurrentRequestResult)
+ {
+ (*iCurrentRequestResult) = (KErrNone == aError);
+ }
+
+ iCurrentRequestResult = 0;
+ if (iTimer)
+ {
+ LOG("cancel timer");
+ delete iTimer;
+ iTimer = 0;
+ }
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ LOG("async stop waiter");
+ iWait->AsyncStop();
+ }
+ }
+ ProcessEmitSignal(aError);
+ }
+ else
+ {
+ // just for internal waiting operation.
+ if (iRequestResult)
+ {
+ (*iRequestResult) = aError;
+ }
+
+ iRequestResult = 0;
+ if (iTimer)
+ {
+ LOG("cancel timer");
+ delete iTimer;
+ iTimer = 0;
+ }
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ LOG("async stop waiter");
+ iWait->AsyncStop();
+ }
+ }
+ }
+
+ END
+}
+
diff --git a/src/nfc/symbian/nearfieldtagasyncrequest_symbian.h b/src/nfc/symbian/nearfieldtagasyncrequest_symbian.h
new file mode 100644
index 00000000..cf5aa96b
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagasyncrequest_symbian.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef NEARFIELDTAGASYNCREQUEST_SYMBIAN_H
+#define NEARFIELDTAGASYNCREQUEST_SYMBIAN_H
+
+#include <qnearfieldtarget.h>
+#include <e32base.h>
+
+class QNearFieldTagImplCommon;
+
+class MNearFieldTagAsyncRequest
+ {
+public:
+ enum TRequestType
+ {
+ ENdefRequest,
+ ETagCommandRequest,
+ ETagCommandsRequest,
+ ENull
+ };
+
+public:
+ MNearFieldTagAsyncRequest(QNearFieldTagImplCommon& aOperator);
+
+ virtual ~MNearFieldTagAsyncRequest();
+ virtual void IssueRequest() = 0;
+ virtual void ProcessResponse(TInt aError);
+
+ // inline to get fast speed since this function is used internally
+ // to convert async ndef request to sync.
+ virtual void ProcessTimeout() = 0;
+
+ virtual void ProcessWaitRequestCompleted(TInt aError);
+
+ // emit signal defined in QNearFieldTarget
+ virtual void ProcessEmitSignal(TInt aError) = 0;
+
+ // should call iOperator->handleResponse(id, response)
+ virtual void HandleResponse(TInt aError) = 0;
+
+ virtual TRequestType Type() = 0;
+
+ virtual bool WaitRequestCompleted(int aMsec);
+ virtual int WaitRequestCompletedNoSignal(int aMsec);
+
+ void SetRequestId(QNearFieldTarget::RequestId aId);
+ QNearFieldTarget::RequestId RequestID();
+ static TInt TimeoutCallback(TAny * aObj);
+protected:
+ // Current async request ID.
+ QNearFieldTarget::RequestId iId;
+ // Not own.
+ QNearFieldTagImplCommon& iOperator;
+
+ // Own.
+ CActiveSchedulerWait * iWait;
+ // Own.
+ CPeriodic * iTimer;
+ TBool iRequestIssued;
+
+ int iMsecs;
+ bool iSendSignal;
+ volatile int * iRequestResult;
+
+ volatile bool * iCurrentRequestResult;
+ };
+
+#endif // NEARFIELDTAGASYNCREQUEST_SYMBIAN_H
diff --git a/src/nfc/symbian/nearfieldtagcommandrequest_symbian.cpp b/src/nfc/symbian/nearfieldtagcommandrequest_symbian.cpp
new file mode 100644
index 00000000..79a9f0a8
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagcommandrequest_symbian.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "nearfieldtagcommandrequest_symbian.h"
+#include "nearfieldutility_symbian.h"
+#include "nearfieldtagimplcommon_symbian.h"
+#include "debug.h"
+
+NearFieldTagCommandRequest::NearFieldTagCommandRequest(QNearFieldTagImplCommon& aOperator) : MNearFieldTagAsyncRequest(aOperator)
+{
+}
+
+NearFieldTagCommandRequest::~NearFieldTagCommandRequest()
+{
+ BEGIN
+ if (iRequestIssued)
+ {
+ iOperator.DoCancelSendCommand();
+ }
+ END
+}
+
+void NearFieldTagCommandRequest::IssueRequest()
+{
+ BEGIN
+
+ iOperator.DoSendCommand(iCommand, this);
+ iRequestIssued = ETrue;
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ // start timer here
+ LOG("Start timer");
+ TCallBack callback(MNearFieldTagAsyncRequest::TimeoutCallback, this);
+ iTimer->Start(iMsecs, iMsecs, callback);
+ }
+ }
+
+ END
+}
+
+bool NearFieldTagCommandRequest::IssueRequestNoDefer()
+{
+ BEGIN
+ iRequestIssued = iOperator.DoSendCommand(iCommand, this, false);
+ return iRequestIssued;
+}
+
+void NearFieldTagCommandRequest::CommandComplete(TInt aError)
+{
+ BEGIN
+ iRequestIssued = EFalse;
+ ProcessResponse(HandlePassiveCommand(aError));
+ END
+}
+
+
+void NearFieldTagCommandRequest::ProcessEmitSignal(TInt aError)
+{
+ BEGIN
+ LOG(aError);
+ if (aError != KErrNone)
+ {
+ iOperator.EmitError(aError, iId);
+ }
+ END
+}
+
+void NearFieldTagCommandRequest::ProcessTimeout()
+{
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ if (iRequestIssued)
+ {
+ iOperator.DoCancelSendCommand();
+ iRequestIssued = EFalse;
+ }
+ ProcessResponse(HandlePassiveCommand(KErrTimedOut));
+ }
+ }
+}
+
+void NearFieldTagCommandRequest::HandleResponse(TInt aError)
+{
+ BEGIN
+ LOG(aError);
+ if (aError == KErrNone)
+ {
+ iOperator.HandleResponse(iId, iCommand, iRequestResponse, iSendSignal);
+ }
+ END
+}
+
+TInt NearFieldTagCommandRequest::HandlePassiveCommand(TInt aError)
+{
+ BEGIN
+ TInt result = aError;
+ // check if the command is passive ack
+ if (iCommand.count() == 6)
+ {
+ // it may be the select sector packet 2 command for tag type 2
+ if ((iCommand.at(1) == 0) && (iCommand.at(2) == 0) && (iCommand.at(3) == 0))
+ {
+ result = KErrNone;
+ if (KErrTimedOut == aError)
+ {
+ iResponse->Append(0x0A);
+ }
+ else
+ {
+ iResponse->Append(0x05);
+ }
+ }
+ }
+ iRequestResponse = QNFCNdefUtility::TDesC2QByteArray(*iResponse);
+ END
+ return result;
+}
diff --git a/src/nfc/symbian/nearfieldtagcommandrequest_symbian.h b/src/nfc/symbian/nearfieldtagcommandrequest_symbian.h
new file mode 100644
index 00000000..6ff06243
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagcommandrequest_symbian.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEARFIELDTAGCOMMANDREQUEST_SYMBIAN_H
+#define NEARFIELDTAGCOMMANDREQUEST_SYMBIAN_H
+
+#include "nearfieldtagasyncrequest_symbian.h"
+#include "nearfieldtagoperationcallback_symbian.h"
+
+class NearFieldTagCommandRequest : public MNearFieldTagAsyncRequest,
+ public MNearFieldTagOperationCallback
+ {
+public:
+ NearFieldTagCommandRequest(QNearFieldTagImplCommon& aOperator);
+ ~NearFieldTagCommandRequest();
+ void IssueRequest();
+ bool IssueRequestNoDefer();
+ void ProcessTimeout();
+ void ProcessEmitSignal(TInt aError);
+ void HandleResponse(TInt aError);
+ void SetInputCommand(QByteArray aCommand) { iCommand = aCommand; }
+ void SetResponseBuffer(RBuf8 * aResponse) { iResponse = aResponse; }
+ QString GetRequestCommand() { return iCommand; }
+ TRequestType Type() { return ETagCommandRequest; }
+private:
+ void CommandComplete(TInt aError);
+ TInt HandlePassiveCommand(TInt aError);
+ QByteArray iCommand;
+ // Not own
+ RBuf8 * iResponse;
+ QByteArray iRequestResponse;
+ };
+
+#endif
diff --git a/src/nfc/symbian/nearfieldtagcommandsrequest_symbian.cpp b/src/nfc/symbian/nearfieldtagcommandsrequest_symbian.cpp
new file mode 100644
index 00000000..5d3a3816
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagcommandsrequest_symbian.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "nearfieldtagcommandsrequest_symbian.h"
+#include "nearfieldutility_symbian.h"
+#include "nearfieldtagimplcommon_symbian.h"
+#include "debug.h"
+
+NearFieldTagCommandsRequest::NearFieldTagCommandsRequest(QNearFieldTagImplCommon& aOperator) : MNearFieldTagAsyncRequest(aOperator)
+{
+ iCurrentCommand = 0;
+ iRequestCancelled = EFalse;
+}
+
+NearFieldTagCommandsRequest::~NearFieldTagCommandsRequest()
+{
+ BEGIN
+ iRequestCancelled = ETrue;
+ if (iRequestIssued)
+ {
+ iOperator.DoCancelSendCommand();
+ }
+ END
+}
+
+void NearFieldTagCommandsRequest::IssueRequest()
+{
+ BEGIN
+ LOG("current command index = "<<iCurrentCommand);
+ LOG("commands count = "<<iCommands.count());
+ iRequestIssued = ETrue;
+ if (iCurrentCommand < iCommands.count())
+ {
+ if (iWait && (iCurrentCommand == 0))
+ {
+ if (iWait->IsStarted() && !iTimer->IsActive())
+ {
+ // start timer here
+ LOG("Start timer");
+ TCallBack callback(MNearFieldTagAsyncRequest::TimeoutCallback, this);
+ iTimer->Start(iMsecs, iMsecs, callback);
+ }
+ }
+ iOperator.DoSendCommand(iCommands.at(iCurrentCommand), this);
+ ++iCurrentCommand;
+ }
+ END
+}
+
+bool NearFieldTagCommandsRequest::IssueRequestNoDefer()
+{
+ BEGIN
+ if (iCommands.count() > 0)
+ {
+ iRequestIssued = iOperator.DoSendCommand(iCommands.at(0), this, false);
+ ++iCurrentCommand;
+ }
+ END
+ return iRequestIssued;
+}
+
+void NearFieldTagCommandsRequest::ProcessResponse(TInt aError)
+{
+ BEGIN
+ LOG("error is "<<aError);
+ QByteArray result;
+ if (KErrNone == aError)
+ {
+ result = QNFCNdefUtility::TDesC2QByteArray(*iResponse);
+ LOG("result is "<<result);
+ LOG("clear the buffer");
+ iResponse->Zero();
+ iDecodedResponses.append(iOperator.decodeResponse(iCommands.at(iCurrentCommand - 1), result));
+ }
+ else
+ {
+ // error occurs
+ LOG("error occurs, append QVariant() to rest list");
+ for (--iCurrentCommand; iCurrentCommand < iCommands.count(); ++iCurrentCommand)
+ {
+ iDecodedResponses.append(QVariant());
+ }
+ }
+ iRequestIssued = EFalse;
+ if (!iRequestCancelled && (iCurrentCommand < iCommands.count()))
+ {
+ LOG("issue another command in command list");
+ IssueRequest();
+ }
+ else
+ {
+ // all commands finished
+ LOG("all commands completed");
+ MNearFieldTagAsyncRequest::ProcessResponse(aError);
+ }
+ END
+}
+
+void NearFieldTagCommandsRequest::HandleResponse(TInt aError)
+{
+ BEGIN
+ iOperator.HandleResponse(iId, iDecodedResponses, aError);
+ END
+}
+
+void NearFieldTagCommandsRequest::CommandComplete(TInt aError)
+{
+ BEGIN
+ ProcessResponse(HandlePassiveCommand(aError));
+ END
+}
+
+void NearFieldTagCommandsRequest::ProcessEmitSignal(TInt aError)
+{
+ BEGIN
+ LOG(aError);
+ if (aError != KErrNone)
+ {
+ iOperator.EmitError(aError, iId);
+ }
+ END
+}
+
+void NearFieldTagCommandsRequest::ProcessTimeout()
+{
+ BEGIN
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ if (iRequestIssued)
+ {
+ iOperator.DoCancelSendCommand();
+ iRequestCancelled = ETrue;
+ iRequestIssued = EFalse;
+ }
+ LOG("wait timeout");
+ ProcessResponse(HandlePassiveCommand(KErrTimedOut));
+ }
+ }
+ END
+}
+
+TInt NearFieldTagCommandsRequest::HandlePassiveCommand(TInt aError)
+{
+ BEGIN
+ TInt result = aError;
+ TInt index = (iCurrentCommand == 0) ? iCurrentCommand : (iCurrentCommand - 1);
+ QByteArray command = iCommands.at(index);
+ // check if the command is passive ack
+ if (command.count() == 6)
+ {
+ // it may be the select sector packet 2 command for tag type 2
+ if ((command.at(1) == 0) && (command.at(2) == 0) && (command.at(3) == 0))
+ {
+ iResponse->Zero();
+ if (KErrTimedOut == aError)
+ {
+ result = KErrNone;
+ iResponse->Append(0x0A);
+ }
+ else
+ {
+ iResponse->Append(0x05);
+ }
+ }
+ }
+ END
+ return result;
+}
diff --git a/src/nfc/symbian/nearfieldtagcommandsrequest_symbian.h b/src/nfc/symbian/nearfieldtagcommandsrequest_symbian.h
new file mode 100644
index 00000000..605d691f
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagcommandsrequest_symbian.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef NEARFIELDTAGCOMMANDSREQUEST_SYMBIAN_H
+#define NEARFIELDTAGCOMMANDSREQUEST_SYMBIAN_H
+
+#include "nearfieldtagasyncrequest_symbian.h"
+#include "nearfieldtagoperationcallback_symbian.h"
+#include <QVariantList>
+
+class NearFieldTagCommandsRequest : public MNearFieldTagAsyncRequest,
+ public MNearFieldTagOperationCallback
+ {
+public:
+ NearFieldTagCommandsRequest(QNearFieldTagImplCommon& aOperator);
+ ~NearFieldTagCommandsRequest();
+ void IssueRequest();
+ bool IssueRequestNoDefer();
+ void ProcessResponse(TInt aError);
+ void ProcessEmitSignal(TInt aError);
+ void HandleResponse(TInt aError);
+ void ProcessTimeout();
+ void SetInputCommands(QList<QByteArray> aCommands) { iCommands = aCommands; }
+ void SetResponseBuffer(RBuf8 * aResponse) { iResponse = aResponse; }
+ TRequestType Type() { return ETagCommandsRequest; }
+private:
+ void CommandComplete(TInt aError);
+ TInt HandlePassiveCommand(TInt aError);
+
+ QList<QByteArray> iCommands;
+ QVariantList iDecodedResponses;
+ // Not own
+ RBuf8 * iResponse;
+ int iCurrentCommand;
+ TBool iRequestCancelled;
+ };
+#endif
diff --git a/src/nfc/symbian/nearfieldtagimpl_symbian.h b/src/nfc/symbian/nearfieldtagimpl_symbian.h
new file mode 100644
index 00000000..00d2ec03
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagimpl_symbian.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNEARFIELDTAGIMPL_H
+#define QNEARFIELDTAGIMPL_H
+
+#include "nearfieldtagimplcommon_symbian.h"
+#include "debug.h"
+
+class QNearFieldTagType1Symbian;
+class QNearFieldTagType2Symbian;
+class QNearFieldTagType3Symbian;
+class QNearFieldTagType4Symbian;
+
+template<typename TAGTYPE>
+struct TagConstValue
+{
+ enum { MaxResponseSize = 4096, Timeout = 100 * 1000 };
+};
+
+template<>
+struct TagConstValue<QNearFieldTagType1Symbian>
+{
+ enum { MaxResponseSize = 131, Timeout = 5 * 1000 };
+};
+
+template<>
+struct TagConstValue<QNearFieldTagType2Symbian>
+{
+ enum { MaxResponseSize = 18, Timeout = 5 * 1000 };
+};
+
+template<>
+struct TagConstValue<QNearFieldTagType3Symbian>
+{
+ enum { MaxResponseSize = 256, Timeout = 500 * 1000 };
+};
+
+template <typename TAGTYPE>
+class QNearFieldTagImpl : public QNearFieldTagImplCommon
+{
+public: // From MNearFieldTargetOperation
+
+ void HandleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted);
+ void HandleResponse(const QNearFieldTarget::RequestId &id, const QVariantList& response, int error);
+ QVariant decodeResponse(const QByteArray& command, const QByteArray& response);
+
+ void EmitNdefMessageRead(const QNdefMessage &message);
+ void EmitNdefMessagesWritten();
+ void EmitRequestCompleted(const QNearFieldTarget::RequestId &id);
+ void EmitError(int error, const QNearFieldTarget::RequestId &id);
+
+public:
+ QNearFieldTagImpl(CNearFieldNdefTarget *tag);
+};
+
+template<typename TAGTYPE>
+QNearFieldTagImpl<TAGTYPE>::QNearFieldTagImpl(CNearFieldNdefTarget *tag) : QNearFieldTagImplCommon(tag)
+{
+ TRAP_IGNORE(mResponse.CreateL(TagConstValue<TAGTYPE>::MaxResponseSize));
+ mTimeout = TagConstValue<TAGTYPE>::Timeout;
+}
+
+template<typename TAGTYPE>
+void QNearFieldTagImpl<TAGTYPE>::HandleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted)
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+ tag->handleTagOperationResponse(id, command, response, emitRequestCompleted);
+ END
+}
+
+template<typename TAGTYPE>
+void QNearFieldTagImpl<TAGTYPE>::HandleResponse(const QNearFieldTarget::RequestId &id, const QVariantList& response, int error)
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+ tag->setResponseForRequest(id, response, (error == KErrNone));
+ END
+}
+
+template<typename TAGTYPE>
+QVariant QNearFieldTagImpl<TAGTYPE>::decodeResponse(const QByteArray& command, const QByteArray& response)
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+ END
+ return tag->decodeResponse(command, response);
+}
+
+template<typename TAGTYPE>
+void QNearFieldTagImpl<TAGTYPE>::EmitNdefMessageRead(const QNdefMessage &message)
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+ int err;
+ QT_TRYCATCH_ERROR(err, emit tag->ndefMessageRead(message));
+ Q_UNUSED(err);
+ END
+}
+
+template<typename TAGTYPE>
+void QNearFieldTagImpl<TAGTYPE>::EmitNdefMessagesWritten()
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+ int err;
+ QT_TRYCATCH_ERROR(err, emit tag->ndefMessagesWritten());
+ Q_UNUSED(err);
+ END
+}
+
+template<typename TAGTYPE>
+void QNearFieldTagImpl<TAGTYPE>::EmitRequestCompleted(const QNearFieldTarget::RequestId &id)
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+ int err;
+ QT_TRYCATCH_ERROR(err, emit tag->requestCompleted(id));
+ Q_UNUSED(err);
+ END
+}
+
+template<typename TAGTYPE>
+void QNearFieldTagImpl<TAGTYPE>::EmitError(int error, const QNearFieldTarget::RequestId &id)
+{
+ BEGIN
+ TAGTYPE * tag = static_cast<TAGTYPE *>(this);
+
+ int err = KErrNone;
+ try {
+ QMetaObject::invokeMethod(tag, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, SymbianError2QtError(error)),
+ Q_ARG(QNearFieldTarget::RequestId, id));
+ } catch (const std::exception &ex) {
+ err = qt_symbian_exception2Error(ex);
+ }
+
+ Q_UNUSED(err);
+ END
+}
+
+#endif // QNEARFIELDTAGIMPL_H
diff --git a/src/nfc/symbian/nearfieldtagimplcommon_symbian.cpp b/src/nfc/symbian/nearfieldtagimplcommon_symbian.cpp
new file mode 100644
index 00000000..bbfba7fc
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagimplcommon_symbian.cpp
@@ -0,0 +1,596 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nearfieldtagimplcommon_symbian.h"
+
+
+bool QNearFieldTagImplCommon::DoReadNdefMessages(MNearFieldNdefOperationCallback * const aCallback)
+{
+ BEGIN
+ int error = KErrGeneral;
+ CNearFieldNdefTarget * ndefTarget = mTag->CastToNdefTarget();
+ if (ndefTarget)
+ {
+ LOG("switched to ndef connection");
+ ndefTarget->SetNdefOperationCallback(aCallback);
+ mMessageList.Reset();
+ error = ndefTarget->ndefMessages(mMessageList);
+ LOG("error code is"<<error);
+ }
+
+ if (error != KErrNone)
+ {
+ aCallback->ReadComplete(error, 0);
+ }
+ END
+ return (error == KErrNone);
+}
+
+
+bool QNearFieldTagImplCommon::DoSetNdefMessages(const QList<QNdefMessage> &messages, MNearFieldNdefOperationCallback * const aCallback)
+{
+ BEGIN
+ int error = KErrGeneral;
+ CNearFieldNdefTarget * ndefTarget = mTag->CastToNdefTarget();
+
+ if (ndefTarget)
+ {
+ ndefTarget->SetNdefOperationCallback(aCallback);
+ if (ndefTarget)
+ {
+ mInputMessageList.ResetAndDestroy();
+ TRAP( error,
+ for (int i = 0; i < messages.count(); ++i)
+ {
+ mInputMessageList.Append(QNFCNdefUtility::QNdefMsg2CNdefMsgL(messages.at(i)));
+ }
+ )
+
+ if (error == KErrNone)
+ {
+ ndefTarget->setNdefMessages(mInputMessageList);
+ }
+ }
+ }
+ if (error != KErrNone)
+ {
+ aCallback->WriteComplete(error);
+ }
+ END
+ return (error == KErrNone);
+}
+
+
+bool QNearFieldTagImplCommon::DoHasNdefMessages()
+{
+ BEGIN
+
+ LOG("use async request to check ndef message");
+ NearFieldTagNdefRequest * readNdefRequest = new NearFieldTagNdefRequest(*this);
+
+ QNearFieldTarget::RequestId requestId;
+
+ if (readNdefRequest)
+ {
+ readNdefRequest->SetRequestId(requestId);
+ readNdefRequest->SetNdefRequestType(NearFieldTagNdefRequest::EReadRequest);
+
+ if (!_isProcessingRequest())
+ {
+ // issue the request
+ LOG("the request will be issued at once");
+ mCurrentRequest = readNdefRequest;
+
+ mPendingRequestList.append(readNdefRequest);
+ readNdefRequest->IssueRequest();
+ }
+ else
+ {
+ mPendingRequestList.append(readNdefRequest);
+ }
+
+ readNdefRequest->WaitRequestCompletedNoSignal(5000);
+ if (mMessageList.Count() == 0)
+ {
+ END
+ return false;
+ }
+ else
+ {
+ mMessageList.Reset();
+ END
+ return true;
+ }
+ }
+ else
+ {
+ LOG("unexpect error to create async request");
+ END
+ return false;
+ }
+}
+
+
+bool QNearFieldTagImplCommon::DoSendCommand(const QByteArray& command, MNearFieldTagOperationCallback * const aCallback, bool deferred)
+{
+ BEGIN
+ int error = (mResponse.MaxLength() == 0) ? KErrGeneral : KErrNone;
+
+ if ((KErrNone == error) && (command.count() > 0))
+ {
+ CNearFieldTag * tag = mTag->CastToTag();
+
+ if (tag)
+ {
+ tag->SetTagOperationCallback(aCallback);
+ TPtrC8 cmd = QNFCNdefUtility::QByteArray2TPtrC8(command);
+ mResponse.Zero();
+ error = tag->RawModeAccess(cmd, mResponse, mTimeout);
+ }
+ else
+ {
+ error = KErrGeneral;
+ }
+ }
+ else
+ {
+ if (deferred)
+ {
+ aCallback->CommandComplete(error);
+ }
+ }
+ END
+ return (error == KErrNone);
+}
+
+
+bool QNearFieldTagImplCommon::IssueNextRequest(QNearFieldTarget::RequestId aId)
+{
+ BEGIN
+ // find the request after current request
+ int index = mPendingRequestList.indexOf(mCurrentRequest);
+ LOG("index = "<<index);
+ if ((index < 0) || (index == mPendingRequestList.count() - 1))
+ {
+ // no next request
+ mCurrentRequest = 0;
+ END
+ return false;
+ }
+ else
+ {
+ if (aId == mCurrentRequest->RequestID())
+ {
+ mCurrentRequest = mPendingRequestList.at(index + 1);
+ mCurrentRequest->IssueRequest();
+ }
+ else
+ {
+ LOG("re-entry happened");
+ }
+
+ END
+ return true;
+ }
+}
+
+
+void QNearFieldTagImplCommon::RemoveRequestFromQueue(QNearFieldTarget::RequestId aId)
+{
+ BEGIN
+ for(int i = 0; i < mPendingRequestList.count(); ++i)
+ {
+ MNearFieldTagAsyncRequest * request = mPendingRequestList.at(i);
+ if (request->RequestID() == aId)
+ {
+ LOG("remove request id");
+ mPendingRequestList.removeAt(i);
+ break;
+ }
+ }
+ END
+}
+
+
+QNearFieldTarget::RequestId QNearFieldTagImplCommon::AllocateRequestId()
+{
+ BEGIN
+ QNearFieldTarget::RequestIdPrivate * p = new QNearFieldTarget::RequestIdPrivate;
+ QNearFieldTarget::RequestId id(p);
+ END
+ return id;
+}
+
+QNearFieldTagImplCommon::QNearFieldTagImplCommon(CNearFieldNdefTarget *tag) : mTag(tag)
+{
+ mCurrentRequest = 0;
+}
+
+
+QNearFieldTagImplCommon::~QNearFieldTagImplCommon()
+{
+ BEGIN
+ LOG("pending request count is "<<mPendingRequestList.count());
+ for (int i = 0; i < mPendingRequestList.count(); ++i)
+ {
+ delete mPendingRequestList[i];
+ }
+
+ mPendingRequestList.clear();
+ mCurrentRequest = 0;
+
+ delete mTag;
+
+ mMessageList.Close();
+ mInputMessageList.ResetAndDestroy();
+ mInputMessageList.Close();
+
+ mResponse.Close();
+ END
+}
+
+
+bool QNearFieldTagImplCommon::_hasNdefMessage()
+{
+ return DoHasNdefMessages();
+}
+
+
+QNearFieldTarget::RequestId QNearFieldTagImplCommon::_ndefMessages()
+{
+ BEGIN
+ NearFieldTagNdefRequest * readNdefRequest = new NearFieldTagNdefRequest(*this);
+ QNearFieldTarget::RequestId requestId = AllocateRequestId();
+
+ if (readNdefRequest)
+ {
+ LOG("read ndef request created");
+ readNdefRequest->SetRequestId(requestId);
+ readNdefRequest->SetNdefRequestType(NearFieldTagNdefRequest::EReadRequest);
+
+ if (!_isProcessingRequest())
+ {
+ LOG("the request will be issued at once");
+ // issue the request
+ mCurrentRequest = readNdefRequest;
+ mPendingRequestList.append(readNdefRequest);
+ readNdefRequest->IssueRequest();
+ }
+ else
+ {
+ mPendingRequestList.append(readNdefRequest);
+ }
+ }
+ else
+ {
+ EmitError(KErrNoMemory, requestId);
+ }
+ END
+
+ return requestId;
+}
+
+
+QNearFieldTarget::RequestId QNearFieldTagImplCommon::_setNdefMessages(const QList<QNdefMessage> &messages)
+{
+ BEGIN
+ NearFieldTagNdefRequest * writeNdefRequest = new NearFieldTagNdefRequest(*this);
+ QNearFieldTarget::RequestId requestId = AllocateRequestId();
+
+ if (writeNdefRequest)
+ {
+ LOG("write ndef request created");
+ writeNdefRequest->SetRequestId(requestId);
+ writeNdefRequest->SetNdefRequestType(NearFieldTagNdefRequest::EWriteRequest);
+ writeNdefRequest->SetInputNdefMessages(messages);
+
+ if (!_isProcessingRequest())
+ {
+ // issue the request
+ LOG("the request will be issued at once");
+ mCurrentRequest = writeNdefRequest;
+ mPendingRequestList.append(writeNdefRequest);
+ writeNdefRequest->IssueRequest();
+ }
+ else
+ {
+ mPendingRequestList.append(writeNdefRequest);
+ }
+ }
+ else
+ {
+ EmitError(KErrNoMemory, requestId);
+ }
+ END
+
+ return requestId;
+}
+
+
+QNearFieldTarget::RequestId QNearFieldTagImplCommon::_sendCommand(const QByteArray &command)
+{
+ BEGIN
+ NearFieldTagCommandRequest * rawCommandRequest = new NearFieldTagCommandRequest(*this);
+ QNearFieldTarget::RequestId requestId = AllocateRequestId();
+
+ if (rawCommandRequest)
+ {
+ LOG("send command request created");
+ rawCommandRequest->SetInputCommand(command);
+ rawCommandRequest->SetRequestId(requestId);
+ rawCommandRequest->SetResponseBuffer(&mResponse);
+
+ if (!_isProcessingRequest())
+ {
+ // issue the request
+ LOG("the request will be issued at once");
+ mCurrentRequest = rawCommandRequest;
+
+ if (rawCommandRequest->IssueRequestNoDefer())
+ {
+ mPendingRequestList.append(rawCommandRequest);
+ }
+ else
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ }
+ else
+ {
+ mPendingRequestList.append(rawCommandRequest);
+ }
+ }
+ else
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ END
+ return requestId;
+}
+
+
+QNearFieldTarget::RequestId QNearFieldTagImplCommon::_sendCommands(const QList<QByteArray> &commands)
+{
+ BEGIN
+ NearFieldTagCommandsRequest * rawCommandsRequest = new NearFieldTagCommandsRequest(*this);
+ QNearFieldTarget::RequestId requestId = AllocateRequestId();
+
+ if (rawCommandsRequest)
+ {
+ LOG("send commands request created");
+ rawCommandsRequest->SetInputCommands(commands);
+ rawCommandsRequest->SetRequestId(requestId);
+ rawCommandsRequest->SetResponseBuffer(&mResponse);
+
+ if (!_isProcessingRequest())
+ {
+ // issue the request
+ LOG("the request will be issued at once");
+ mCurrentRequest = rawCommandsRequest;
+
+ if (rawCommandsRequest->IssueRequestNoDefer())
+ {
+ mPendingRequestList.append(rawCommandsRequest);
+ }
+ else
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ }
+ else
+ {
+ mPendingRequestList.append(rawCommandsRequest);
+ }
+ }
+ else
+ {
+ END
+ return QNearFieldTarget::RequestId();
+ }
+ END
+ return requestId;
+}
+
+
+QByteArray QNearFieldTagImplCommon::_uid() const
+{
+ BEGIN
+ if (mUid.isEmpty())
+ {
+ mUid = QNFCNdefUtility::TDesC2QByteArray(mTag->Uid());
+ LOG(mUid);
+ }
+ END
+ return mUid;
+}
+
+
+bool QNearFieldTagImplCommon::_isProcessingRequest() const
+{
+ BEGIN
+ bool result = mPendingRequestList.count() > 0;
+ LOG(result);
+ END
+ return result;
+
+}
+
+
+bool QNearFieldTagImplCommon::_waitForRequestCompleted(const QNearFieldTarget::RequestId &id, int msecs)
+{
+ BEGIN
+ int index = -1;
+ for (int i = 0; i < mPendingRequestList.count(); ++i)
+ {
+ if (id == mPendingRequestList.at(i)->RequestID())
+ {
+ index = i;
+ break;
+ }
+ }
+
+ if (index < 0)
+ {
+ // request ID is not in pending list. So maybe it is already completed.
+ END
+ return false;
+ }
+
+ MNearFieldTagAsyncRequest * request = mPendingRequestList.at(index);
+ LOG("get the request from pending request list");
+ END
+ return request->WaitRequestCompleted(msecs);
+}
+
+
+bool QNearFieldTagImplCommon::_waitForRequestCompletedNoSignal(const QNearFieldTarget::RequestId &id, int msecs)
+{
+ BEGIN
+ int index = -1;
+ for (int i = 0; i < mPendingRequestList.count(); ++i)
+ {
+ if (id == mPendingRequestList.at(i)->RequestID())
+ {
+ index = i;
+ break;
+ }
+ }
+
+ if (index < 0)
+ {
+ // request ID is not in pending list. So either it may not be issued, or has already completed
+ END
+ return false;
+ }
+
+ MNearFieldTagAsyncRequest * request = mPendingRequestList.at(index);
+ LOG("get the request from pending request list");
+ END
+ return (KErrNone == request->WaitRequestCompletedNoSignal(msecs));
+}
+
+void QNearFieldTagImplCommon::DoCancelSendCommand()
+{
+ BEGIN
+ CNearFieldTag * tag = mTag->CastToTag();
+ if (tag)
+ {
+ LOG("Cancel raw command operation");
+ tag->SetTagOperationCallback(0);
+ tag->Cancel();
+ }
+ END
+}
+
+
+void QNearFieldTagImplCommon::DoCancelNdefAccess()
+{
+ BEGIN
+ CNearFieldNdefTarget * ndefTarget = mTag->CastToNdefTarget();
+ if(ndefTarget)
+ {
+ LOG("Cancel ndef operation");
+ ndefTarget->SetNdefOperationCallback(0);
+ ndefTarget->Cancel();
+ }
+ END
+}
+
+
+QNearFieldTarget::Error QNearFieldTagImplCommon::SymbianError2QtError(int error)
+{
+ BEGIN
+ QNearFieldTarget::Error qtError = QNearFieldTarget::InvalidParametersError;
+ switch(error)
+ {
+ case KErrNone:
+ {
+ qtError = QNearFieldTarget::NoError;
+ break;
+ }
+ case KErrNotSupported:
+ {
+ qtError = QNearFieldTarget::UnsupportedError;
+ break;
+ }
+ case KErrTimedOut:
+ {
+ qtError = QNearFieldTarget::NoResponseError;
+ break;
+ }
+ case KErrAccessDenied:
+ case KErrEof:
+ case KErrServerTerminated:
+ {
+ if (mCurrentRequest)
+ {
+ if(mCurrentRequest->Type() == MNearFieldTagAsyncRequest::ENdefRequest)
+ {
+ NearFieldTagNdefRequest * req = static_cast<NearFieldTagNdefRequest *>(mCurrentRequest);
+ if (req->GetNdefRequestType() == NearFieldTagNdefRequest::EReadRequest)
+ {
+ qtError = QNearFieldTarget::NdefReadError;
+ }
+ else if (req->GetNdefRequestType() == NearFieldTagNdefRequest::EWriteRequest)
+ {
+ qtError = QNearFieldTarget::NdefWriteError;
+ }
+ }
+ }
+ break;
+ }
+ case KErrTooBig:
+ {
+ qtError = QNearFieldTarget::TargetOutOfRangeError;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ LOG(qtError);
+ END
+ return qtError;
+}
diff --git a/src/nfc/symbian/nearfieldtagimplcommon_symbian.h b/src/nfc/symbian/nearfieldtagimplcommon_symbian.h
new file mode 100644
index 00000000..0d769863
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagimplcommon_symbian.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEARFIELDTAGIMPLCOMMON_SYMBIAN_H
+#define NEARFIELDTAGIMPLCOMMON_SYMBIAN_H
+
+#include <qnearfieldtarget.h>
+#include <qnearfieldtarget_p.h>
+#include "nearfieldtag_symbian.h"
+#include "nearfieldndeftarget_symbian.h"
+#include "nearfieldutility_symbian.h"
+#include "nearfieldtagasyncrequest_symbian.h"
+
+#include "nearfieldtagoperationcallback_symbian.h"
+#include "nearfieldtagndefoperationcallback_symbian.h"
+
+#include "nearfieldtagndefrequest_symbian.h"
+#include "nearfieldtagcommandrequest_symbian.h"
+#include "nearfieldtagcommandsrequest_symbian.h"
+
+class QNearFieldTagImplCommon
+{
+public:
+ bool DoReadNdefMessages(MNearFieldNdefOperationCallback * const aCallback);
+ bool DoSetNdefMessages(const QList<QNdefMessage> &messages, MNearFieldNdefOperationCallback * const aCallback);
+ bool DoHasNdefMessages();
+ bool DoSendCommand(const QByteArray& command, MNearFieldTagOperationCallback * const aCallback, bool deferred = true);
+ bool IssueNextRequest(QNearFieldTarget::RequestId aId);
+ void RemoveRequestFromQueue(QNearFieldTarget::RequestId aId);
+ QNearFieldTarget::RequestId AllocateRequestId();
+ void DoCancelSendCommand();
+ void DoCancelNdefAccess();
+ QNearFieldTarget::Error SymbianError2QtError(int error);
+
+ virtual void EmitNdefMessageRead(const QNdefMessage &message) = 0;
+ virtual void EmitNdefMessagesWritten() = 0;
+ virtual void EmitRequestCompleted(const QNearFieldTarget::RequestId &id) = 0;
+ virtual void EmitError(int error, const QNearFieldTarget::RequestId &id) = 0;
+ virtual void HandleResponse(const QNearFieldTarget::RequestId &id, const QByteArray &command, const QByteArray &response, bool emitRequestCompleted) = 0;
+ virtual void HandleResponse(const QNearFieldTarget::RequestId &id, const QVariantList& response, int error) = 0;
+ virtual QVariant decodeResponse(const QByteArray& command, const QByteArray& response) = 0;
+
+public:
+ QNearFieldTagImplCommon(CNearFieldNdefTarget *tag);
+ virtual ~QNearFieldTagImplCommon();
+
+protected:
+ bool _hasNdefMessage();
+ QNearFieldTarget::RequestId _ndefMessages();
+ QNearFieldTarget::RequestId _setNdefMessages(const QList<QNdefMessage> &messages);
+
+ void _setAccessMethods(const QNearFieldTarget::AccessMethods& accessMethods)
+ {
+ mAccessMethods = accessMethods;
+ }
+
+ QNearFieldTarget::AccessMethods _accessMethods() const
+ {
+ return mAccessMethods;
+ }
+
+ QNearFieldTarget::RequestId _sendCommand(const QByteArray &command);
+ QNearFieldTarget::RequestId _sendCommands(const QList<QByteArray> &command);
+ bool _waitForRequestCompleted(const QNearFieldTarget::RequestId &id, int msecs = 5000);
+ bool _waitForRequestCompletedNoSignal(const QNearFieldTarget::RequestId &id, int msecs = 5000);
+
+ QByteArray _uid() const;
+
+ bool _isProcessingRequest() const;
+
+protected:
+ CNearFieldNdefTarget * mTag;
+ QNearFieldTarget::AccessMethods mAccessMethods;
+ mutable QByteArray mUid;
+ RPointerArray<CNdefMessage> mMessageList;
+ RBuf8 mResponse;
+
+ QList<MNearFieldTagAsyncRequest *> mPendingRequestList;
+ MNearFieldTagAsyncRequest * mCurrentRequest;
+
+ TTimeIntervalMicroSeconds32 mTimeout;
+ RPointerArray<CNdefMessage> mInputMessageList;
+};
+
+#endif
diff --git a/src/nfc/symbian/nearfieldtagndefoperationcallback_symbian.h b/src/nfc/symbian/nearfieldtagndefoperationcallback_symbian.h
new file mode 100644
index 00000000..594d4396
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagndefoperationcallback_symbian.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEARFIELDNDEFOPERATIONCALLBACK_H
+#define NEARFIELDNDEFOPERATIONCALLBACK_H
+
+#include <e32cmn.h>
+#include <ndefmessage.h>
+class MNearFieldNdefOperationCallback
+ {
+public:
+ virtual void ReadComplete(TInt aError, RPointerArray<CNdefMessage> * aMessages) = 0;
+ virtual void WriteComplete(TInt aError) = 0;
+ };
+
+#endif
diff --git a/src/nfc/symbian/nearfieldtagndefrequest_symbian.cpp b/src/nfc/symbian/nearfieldtagndefrequest_symbian.cpp
new file mode 100644
index 00000000..5ac41b2c
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagndefrequest_symbian.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nearfieldtagndefrequest_symbian.h"
+#include "nearfieldutility_symbian.h"
+#include "nearfieldtagimplcommon_symbian.h"
+#include "debug.h"
+
+NearFieldTagNdefRequest::NearFieldTagNdefRequest(QNearFieldTagImplCommon& aOperator) : MNearFieldTagAsyncRequest(aOperator)
+{
+}
+
+NearFieldTagNdefRequest::~NearFieldTagNdefRequest()
+{
+ BEGIN
+ if (iRequestIssued)
+ {
+ iOperator.DoCancelNdefAccess();
+ }
+ END
+}
+
+void NearFieldTagNdefRequest::IssueRequest()
+{
+ BEGIN
+
+ iRequestIssued = ETrue;
+ LOG(iType);
+ switch(iType)
+ {
+ case EReadRequest:
+ {
+ iOperator.DoReadNdefMessages(this);
+ break;
+ }
+ case EWriteRequest:
+ {
+ iOperator.DoSetNdefMessages(iMessages, this);
+ break;
+ }
+ default:
+ {
+ iRequestIssued = EFalse;
+ break;
+ }
+ }
+
+ END
+}
+
+void NearFieldTagNdefRequest::ReadComplete(TInt aError, RPointerArray<CNdefMessage> * aMessage)
+{
+ BEGIN
+ LOG(aError);
+ iRequestIssued = EFalse;
+ TRAP_IGNORE(
+ if (aMessage != 0)
+ {
+ for(int i = 0; i < aMessage->Count(); ++i)
+ {
+ QNdefMessage message = QNFCNdefUtility::CNdefMsg2QNdefMsgL(*(*aMessage)[i]);
+ iReadMessages.append(message);
+ }
+ }
+ else
+ {
+ iReadMessages.clear();
+ }
+ ) // TRAP end
+ ProcessResponse(aError);
+ END
+}
+
+void NearFieldTagNdefRequest::WriteComplete(TInt aError)
+{
+ BEGIN
+ iRequestIssued = EFalse;
+ ProcessResponse(aError);
+ END
+}
+
+void NearFieldTagNdefRequest::ProcessEmitSignal(TInt aError)
+{
+ BEGIN
+ LOG("error code is "<<aError<<" request type is "<<iType);
+ if (aError != KErrNone)
+ {
+ iOperator.EmitError(aError, iId);
+ }
+ else
+ {
+ if (EReadRequest == iType)
+ {
+ // since there is no error, iReadMessages can't be NULL.
+
+ LOG("message count is "<<iReadMessages.count());
+ for(int i = 0; i < iReadMessages.count(); ++i)
+ {
+ LOG("emit signal ndef message read");
+ iOperator.EmitNdefMessageRead(iReadMessages.at(i));
+ }
+ iOperator.EmitRequestCompleted(iId);
+ }
+ else if (EWriteRequest == iType)
+ {
+ iOperator.EmitNdefMessagesWritten();
+ //iOperator.EmitRequestCompleted(iId);
+ }
+ }
+ END
+}
+
+void NearFieldTagNdefRequest::ProcessTimeout()
+{
+ if (iWait)
+ {
+ if (iWait->IsStarted())
+ {
+ if (iRequestIssued)
+ {
+ iOperator.DoCancelNdefAccess();
+ iRequestIssued = EFalse;
+ }
+ ProcessResponse(KErrTimedOut);
+ }
+ }
+}
+
+void NearFieldTagNdefRequest::HandleResponse(TInt /*aError*/)
+{
+ BEGIN
+ END
+}
diff --git a/src/nfc/symbian/nearfieldtagndefrequest_symbian.h b/src/nfc/symbian/nearfieldtagndefrequest_symbian.h
new file mode 100644
index 00000000..f55829e5
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagndefrequest_symbian.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef NEARFIELDTAGNDEFREQUEST_SYMBIAN_H
+#define NEARFIELDTAGNDEFREQUEST_SYMBIAN_H
+
+#include "nearfieldtagasyncrequest_symbian.h"
+#include "nearfieldtagndefoperationcallback_symbian.h"
+
+class NearFieldTagNdefRequest : public MNearFieldTagAsyncRequest,
+ public MNearFieldNdefOperationCallback
+ {
+public:
+ enum TNdefRequestType
+ {
+ EReadRequest,
+ EWriteRequest,
+ ECheckRequest
+ };
+public:
+ NearFieldTagNdefRequest(QNearFieldTagImplCommon& aOperator);
+ ~NearFieldTagNdefRequest();
+ void IssueRequest();
+ void ProcessEmitSignal(TInt aError);
+ void ProcessTimeout();
+ void HandleResponse(TInt aError);
+ void SetNdefRequestType(TNdefRequestType aType) { iType = aType; }
+ void SetInputNdefMessages(QList<QNdefMessage> aMessages) { iMessages = aMessages; }
+ TNdefRequestType GetNdefRequestType() { return iType; }
+ TRequestType Type() { return ENdefRequest; }
+
+private:
+ void ReadComplete(TInt aError, RPointerArray<CNdefMessage> * aMessages);
+ void WriteComplete(TInt aError);
+
+private:
+ TNdefRequestType iType;
+ QList<QNdefMessage> iMessages;
+
+ QList<QNdefMessage> iReadMessages;
+ };
+#endif
diff --git a/src/nfc/symbian/nearfieldtagoperationcallback_symbian.h b/src/nfc/symbian/nearfieldtagoperationcallback_symbian.h
new file mode 100644
index 00000000..f80da9c5
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtagoperationcallback_symbian.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEARFIELDTAGOPERATIONCALLBACK_H
+#define NEARFIELDTAGOPERATIONCALLBACK_H
+
+class MNearFieldTagOperationCallback
+ {
+public:
+ virtual void CommandComplete(TInt aError) = 0;
+ };
+
+#endif
diff --git a/src/nfc/symbian/nearfieldtargetfactory_symbian.cpp b/src/nfc/symbian/nearfieldtargetfactory_symbian.cpp
new file mode 100644
index 00000000..03a032a9
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtargetfactory_symbian.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nearfieldtargetfactory_symbian.h"
+#include <nfcserver.h>
+#include <nfctag.h>
+#include <nfctype1connection.h>
+#include <nfctype2connection.h>
+#include <nfctype3connection.h>
+#include <iso14443connection.h>
+#include <mifareclassicconnection.h>
+#include "qnearfieldtagtype1_symbian_p.h"
+#include "qnearfieldtagtype2_symbian_p.h"
+#include "qnearfieldtagtype3_symbian_p.h"
+#include "qnearfieldtagtype4_symbian_p.h"
+#include "qnearfieldtagmifare_symbian_p.h"
+#include "qnearfieldllcpdevice_symbian_p.h"
+/*
+ \class TNearFieldTargetFactory
+ \brief The TNearFieldTargetFactory class creates detected target instance according
+ to the input tag information
+
+ \ingroup connectivity-nfc
+ \inmodule QtConnectivity
+ \since 5.0
+*/
+
+/*
+ Create tag type instance according to the tag information in \a aNfcTag and assign
+ the \a aParent as target's parent.
+*/
+template <typename CTAGCONNECTION, typename QTAGTYPE>
+QNearFieldTarget * TNearFieldTargetFactory::CreateTagTypeL(MNfcTag * aNfcTag, RNfcServer& aNfcServer, QObject * aParent)
+{
+ BEGIN
+ // ownership of aNfcTag transferred.
+ CTAGCONNECTION * connection = CTAGCONNECTION::NewLC(aNfcServer);
+ CNearFieldTag * tagType = CNearFieldTag::NewLC(aNfcTag, aNfcServer);
+ tagType->SetConnection(connection);
+ QTAGTYPE * tag= new(ELeave)QTAGTYPE(WrapNdefAccessL(aNfcTag, aNfcServer, tagType), aParent);
+ // walk around, symbian discovery API can't know if tag has Ndef Connection mode when detected
+ tag->setAccessMethods(ConnectionMode2AccessMethods(aNfcTag)|QNearFieldTarget::NdefAccess);
+ CleanupStack::Pop(tagType);
+ CleanupStack::Pop(connection);
+ END
+ return tag;
+}
+
+/*
+ Create target instance according to the tag information in \a aNfcTag and assign
+ the \a aParent as target's parent.
+*/
+
+QNearFieldTarget * TNearFieldTargetFactory::CreateTargetL(MNfcTag * aNfcTag, RNfcServer& aNfcServer, QObject * aParent)
+ {
+ BEGIN
+ QNearFieldTarget * target = 0;
+ if (!aNfcTag)
+ {
+ LOG("llcp device created");
+ target = new (ELeave)QNearFieldLlcpDeviceSymbian(aNfcServer, aParent);
+ }
+ else if(aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENfcType1))
+ {
+ LOG("tag type 1 created");
+ target = CreateTagTypeL<CNfcType1Connection, QNearFieldTagType1Symbian>(aNfcTag, aNfcServer, aParent);
+ }
+ else if (aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENfcType2))
+ {
+ LOG("tag type 2 created");
+ target = CreateTagTypeL<CNfcType2Connection, QNearFieldTagType2Symbian>(aNfcTag, aNfcServer, aParent);
+ }
+ else if (aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENfcType3))
+ {
+ LOG("tag type 3 created");
+ target = CreateTagTypeL<CNfcType3Connection, QNearFieldTagType3Symbian>(aNfcTag, aNfcServer, aParent);
+ }
+ else if (aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENfc14443P4))
+ {
+ LOG("tag type 4 created");
+ target = CreateTagTypeL<CIso14443Connection, QNearFieldTagType4Symbian>(aNfcTag, aNfcServer, aParent);
+ }
+ else if (aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENfcMifareStd))
+ {
+ LOG("tag type mifare created");
+ target = CreateTagTypeL<CMifareClassicConnection, QNearFieldTagMifareSymbian>(aNfcTag, aNfcServer, aParent);
+ }
+ END
+ return target;
+ }
+
+CNearFieldNdefTarget * TNearFieldTargetFactory::WrapNdefAccessL(MNfcTag * aNfcTag, RNfcServer& aNfcServer, CNearFieldTag * aTarget)
+ {
+ BEGIN
+ // walk around, symbian discovery API can't know if tag has Ndef Connection mode when detected
+
+ LOG("Wrap NDEF Access to the tag");
+
+ CNearFieldNdefTarget * ndefTarget = CNearFieldNdefTarget::NewLC(aNfcTag, aNfcServer);
+ ndefTarget->SetRealTarget(aTarget);
+ CleanupStack::Pop(ndefTarget);
+ END
+ return ndefTarget;
+ }
+
+QNearFieldTarget::AccessMethods TNearFieldTargetFactory::ConnectionMode2AccessMethods(MNfcTag * aNfcTag)
+ {
+ BEGIN
+ QNearFieldTarget::AccessMethods accessMethod;
+ if (aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENdefConnection))
+ {
+ LOG("the tag has NDefConnection");
+ accessMethod |= QNearFieldTarget::NdefAccess;
+ }
+ if (!aNfcTag->HasConnectionMode(TNfcConnectionInfo::ENfcUnknownConnectionMode))
+ {
+ LOG("the tag has tag specified access");
+ accessMethod |= QNearFieldTarget::TagTypeSpecificAccess;
+ }
+ END
+ return accessMethod;
+ }
diff --git a/src/nfc/symbian/nearfieldtargetfactory_symbian.h b/src/nfc/symbian/nearfieldtargetfactory_symbian.h
new file mode 100644
index 00000000..2795d9c7
--- /dev/null
+++ b/src/nfc/symbian/nearfieldtargetfactory_symbian.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU General
+ ** Public License version 3.0 as published by the Free Software Foundation
+ ** and appearing in the file LICENSE.GPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU General
+ ** Public License version 3.0 requirements will be met:
+ ** http://www.gnu.org/copyleft/gpl.html.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef NEARFIELDTARGETFACTORY_H_
+#define NEARFIELDTARGETFACTORY_H_
+
+#include <qnearfieldtarget.h>
+#include "nearfieldndeftarget_symbian.h"
+#include "nearfieldtag_symbian.h"
+#include "debug.h"
+
+class MNfcTag;
+class RNfcServer;
+
+class TNearFieldTargetFactory
+ {
+public:
+ static QNearFieldTarget * CreateTargetL(MNfcTag * aNfcTag, RNfcServer& aNfcServer, QObject * aParent);
+private:
+ static CNearFieldNdefTarget * WrapNdefAccessL(MNfcTag * aNfcTag, RNfcServer& aNfcServer, CNearFieldTag * aTarget);
+ static QNearFieldTarget::AccessMethods ConnectionMode2AccessMethods(MNfcTag * aNfcTag);
+
+ template <typename CTAGCONNECTION, typename QTAGTYPE>
+ static QNearFieldTarget * CreateTagTypeL(MNfcTag * aNfcTag, RNfcServer& aNfcServer, QObject * aParent);
+ };
+
+
+#endif /* NEARFIELDTARGETFACTORY_H */
diff --git a/src/nfc/symbian/nearfieldutility_symbian.cpp b/src/nfc/symbian/nearfieldutility_symbian.cpp
new file mode 100644
index 00000000..44a0554d
--- /dev/null
+++ b/src/nfc/symbian/nearfieldutility_symbian.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <ndefmessage.h>
+#include <QtCore/QList>
+#include <e32base.h>
+#include "../qndefmessage.h"
+#include "nearfieldutility_symbian.h"
+#include "debug.h"
+
+CNdefMessage* QNFCNdefUtility::QNdefMsg2CNdefMsgL( const QNdefMessage& msg )
+ {
+ QByteArray payload = msg.toByteArray();
+ CNdefMessage* cmsg = CNdefMessage::NewL();
+ TPtrC8 rawData(reinterpret_cast<const TUint8*>(payload.constData()), payload.size());
+ cmsg->ImportRawDataL(rawData, 0);
+ return cmsg;
+ }
+
+
+QNdefMessage QNFCNdefUtility::CNdefMsg2QNdefMsgL( const CNdefMessage& msg )
+ {
+ BEGIN
+ QNdefMessage result;
+ LOG("CNdefMessage size is "<<msg.SizeL());
+ HBufC8* newBuf = HBufC8::NewL(msg.SizeL());
+ RBuf8 buf;
+ buf.Assign(newBuf);
+ buf.CleanupClosePushL();
+ LOG("export msg to raw data");
+ msg.ExportRawDataL(buf,0);
+ LOG("import raw data to msg");
+ QByteArray qtArray;
+ qtArray.append(reinterpret_cast<const char*>(newBuf->Ptr()),newBuf->Size());
+ result = QNdefMessage::fromByteArray(qtArray);
+ CleanupStack::PopAndDestroy(&buf);
+ END
+ return result;
+ }
+
+TPtrC8 QNFCNdefUtility::QByteArray2TPtrC8(const QByteArray& qbytearray)
+ {
+ TPtrC8 ptr(reinterpret_cast<const TUint8*>(qbytearray.constData()), qbytearray.size());
+ return ptr;
+ }
+
+QByteArray QNFCNdefUtility::TDesC2QByteArray( const TDesC8& des)
+ {
+ QByteArray result;
+ for(int i = 0; i < des.Length(); ++i)
+ {
+ result.append(des[i]);
+ }
+ return result;
+ }
+
+
+HBufC8* QNFCNdefUtility::QString2HBufC8L(const QString& qstring)
+ {
+ TPtrC wide(static_cast<const TUint16*>(qstring.utf16()),qstring.length());
+ HBufC8* newBuf = HBufC8::NewL(wide.Length());
+ TPtr8 des = newBuf->Des();
+ des.Copy(wide);
+ return newBuf;
+ }
+
+QString QNFCNdefUtility::TDesC82QStringL(const TDesC8& aDescriptor)
+ {
+ HBufC* newBuf = NULL;
+ QT_TRAP_THROWING(newBuf = HBufC::NewL(aDescriptor.Length()));
+ TPtr des = newBuf->Des();
+ des.Copy(aDescriptor);
+ QString ret = QString::fromUtf16(newBuf->Ptr(),newBuf->Length());
+ delete newBuf;
+ return ret;
+ }
+
+// timer implementation
+CLlcpTimer* CLlcpTimer::NewL(CActiveSchedulerWait & aWait)
+ {
+ BEGIN
+ CLlcpTimer* self = new (ELeave) CLlcpTimer(aWait);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ END
+ return self;
+ }
+
+/**
+Destructor.
+*/
+CLlcpTimer::~CLlcpTimer()
+ {
+ BEGIN
+ Cancel();
+ END
+ }
+
+/**
+Starts the shutdown timer.
+*/
+void CLlcpTimer::Start(TInt aMSecs)
+ {
+ BEGIN
+ const TUint KDelay = (1000 * aMSecs);
+ After(KDelay);
+ END
+ }
+
+void CLlcpTimer::RunL()
+ {
+ BEGIN
+ if (iWait.IsStarted())
+ {
+ iWait.AsyncStop();
+ }
+ END
+ }
+
+/**
+Constructor
+*/
+CLlcpTimer::CLlcpTimer(CActiveSchedulerWait & aWait) :
+ CTimer(EPriorityNormal),
+ iWait(aWait)
+ {
+ }
+
+/**
+Second phase constructor.
+*/
+void CLlcpTimer::ConstructL()
+ {
+ BEGIN
+ CTimer::ConstructL();
+ CActiveScheduler::Add(this);
+ END
+ }
+
+
diff --git a/src/nfc/symbian/nearfieldutility_symbian.h b/src/nfc/symbian/nearfieldutility_symbian.h
new file mode 100644
index 00000000..de526f03
--- /dev/null
+++ b/src/nfc/symbian/nearfieldutility_symbian.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNFCNDEFUTILITY_SYMBIAN_H_
+#define QNFCNDEFUTILITY_SYMBIAN_H_
+#include <qndefmessage.h>
+#include <e32base.h>
+
+class CNdefMessage;
+
+class CLlcpTimer : public CTimer
+ {
+public:
+
+ static CLlcpTimer* NewL(CActiveSchedulerWait & aWait);
+ virtual ~CLlcpTimer();
+
+ void Start(TInt aMSecs);
+
+private: // From CTimer
+
+ void RunL();
+
+private:
+
+ CLlcpTimer(CActiveSchedulerWait & aWait);
+ void ConstructL();
+
+private:
+
+ CActiveSchedulerWait& iWait; //not own
+ };
+
+class QNdefMessage;
+class QNFCNdefUtility
+{
+public:
+
+ /**
+ * Maps between CNdefMessage and QNdefMessage
+ *
+ */
+ static CNdefMessage* QNdefMsg2CNdefMsgL( const QNdefMessage& msg );
+ static QNdefMessage CNdefMsg2QNdefMsgL( const CNdefMessage& msg );
+
+ static TPtrC8 QByteArray2TPtrC8(const QByteArray& qbytearray);
+ static QByteArray TDesC2QByteArray( const TDesC8& des);
+
+ static HBufC8* QString2HBufC8L(const QString& qstring);
+ static QString TDesC82QStringL(const TDesC8&);
+
+};
+
+#endif /* QNFCNDEFUTILITY_SYMBIAN_H_ */
diff --git a/src/nfc/targetemulator.cpp b/src/nfc/targetemulator.cpp
new file mode 100644
index 00000000..7d77aa17
--- /dev/null
+++ b/src/nfc/targetemulator.cpp
@@ -0,0 +1,382 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "targetemulator_p.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QDateTime>
+
+#include <QtCore/QDebug>
+
+// Implementation of qNfcChecksum
+#include "checksum_p.h"
+
+TagBase::TagBase()
+: lastAccess(0)
+{
+}
+
+TagBase::~TagBase()
+{
+}
+
+static inline quint8 blockByteToAddress(quint8 block, quint8 byte)
+{
+ return ((block & 0x0f) << 3) | (byte & 0x07);
+}
+
+NfcTagType1::NfcTagType1()
+: hr0(0x11), hr1(0x00), memory(120, '\0')
+{
+ // Locked blocks
+ memory[(0x0e << 3) | 0x00] = 0x01;
+ memory[(0x0e << 3) | 0x01] = 0x60;
+}
+
+void NfcTagType1::load(QSettings *settings)
+{
+ settings->beginGroup(QLatin1String("TagType1"));
+
+ hr0 = settings->value(QLatin1String("HR0"), 0x11).toUInt();
+
+ if (!(hr0 & 0x10)) {
+ settings->endGroup();
+ return;
+ }
+
+ hr1 = settings->value(QLatin1String("HR1"), 0x00).toUInt();
+
+ memory = settings->value(QLatin1String("Data")).toByteArray();
+
+ //quint8 nmn = memory.at(8);
+
+ quint8 vno = memory.at(9);
+ if (vno != 0x10)
+ qWarning("Only NFC TagType1 v1.0 behavior is supported.");
+
+ quint8 tms = memory.at(10);
+ if (memory.length() != 8 * (tms + 1))
+ qWarning("Static memory size does not match TMS value.");
+
+ quint8 rwa = memory.at(11);
+ switch (rwa >> 4) {
+ case 0:
+ // Unrestricted read access tag
+ break;
+ default:
+ // tag with unknown read attributes
+ ;
+ }
+
+ switch (rwa & 0x0f) {
+ case 0:
+ // Unrestricted write access tag
+ break;
+ case 0x0f:
+ // Read only tag
+ break;
+ default:
+ // tag with unknown write attributes
+ ;
+ }
+
+ //quint16 lock = (quint8(memory[blockByteToAddress(0x0e, 1)]) << 8) |
+ // quint8(memory[blockByteToAddress(0x0e, 0)]);
+
+ settings->endGroup();
+}
+
+QByteArray NfcTagType1::uid() const
+{
+ lastAccess = QDateTime::currentMSecsSinceEpoch();
+
+ return memory.left(7);
+}
+
+quint8 NfcTagType1::readData(quint8 block, quint8 byte)
+{
+ return memory.at((block << 3) | byte);
+}
+
+QByteArray NfcTagType1::processCommand(const QByteArray &command)
+{
+ lastAccess = QDateTime::currentMSecsSinceEpoch();
+
+ QByteArray response;
+
+ bool tagType1 = (hr0 & 0xf0) == 0x10;
+ bool dynamic = (hr0 & 0x0f) != 0x01;
+
+ if (command.length() == 9) {
+ // static memory model command
+ quint8 opcode = command.at(0);
+ quint8 address = command.at(1);
+ quint8 data = command.at(2);
+ QByteArray uid = command.mid(3, 4);
+
+ // check checksum
+ if (qNfcChecksum(command.constData(), command.length()) != 0)
+ return QByteArray();
+
+ // check UID
+ if (uid != memory.left(4))
+ return QByteArray();
+
+ switch (opcode) {
+ case 0x00: // RALL
+ response.append(hr0);
+ response.append(hr1);
+ response.append(memory.left(120));
+ break;
+ case 0x01: // READ
+ response.append(address);
+ if (address & 0x80)
+ response.append(char(0x00));
+ else
+ response.append(memory.at(address));
+ break;
+ case 0x53: { // WRITE-E
+ quint8 block = address >> 3;
+ if (block == 0x00 || block == 0x0d || block == 0x0e) // locked blocks
+ break;
+
+ quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
+ if ((0x01 << block) & lock) // locked blocks
+ break;
+
+ // FIXME: Test dynamic lock bytes
+
+ memory[address] = data;
+
+ response.append(address);
+ response.append(data);
+ break;
+ }
+ case 0x1a: { // WRITE-NE
+ quint8 block = address >> 3;
+ if (block == 0x00 || block == 0x0d) // locked blocks
+ break;
+
+ quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
+ if ((0x01 << block) & lock) // locked blocks
+ break;
+
+
+ // FIXME: Test dynamic lock bytes
+
+ memory[address] = memory.at(address) | data;
+
+ response.append(address);
+ response.append(memory.at(address));
+ break;
+ }
+ case 0x78: // RID
+ response.append(hr0);
+ response.append(hr1);
+ response.append(memory.left(4));
+ break;
+ }
+ } else if (tagType1 && dynamic && command.length() == 16) {
+ // dynamic memory model command
+ quint8 opcode = command.at(0);
+ quint8 address = command.at(1);
+ QByteArray data = command.mid(2, 8);
+ QByteArray uid = command.mid(10, 4);
+
+ // check checksum
+ if (qNfcChecksum(command.constData(), command.length()) != 0)
+ return QByteArray();
+
+ // check UID
+ if (uid != memory.left(4))
+ return QByteArray();
+
+ switch (opcode) {
+ case 0x10: // RSEG
+ response.append(address);
+ response.append(memory.mid(128 * (address >> 4), 128));
+ break;
+ case 0x02: // READ8
+ response.append(address);
+ response.append(memory.mid(8 * address, 8));
+ break;
+ case 0x54: { // WRITE-E8
+ // locked blocks
+ if (address == 0x00 || address == 0x0d || address == 0x0e || address == 0x0f)
+ break;
+
+ quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
+ if (address <= 0x0e && ((0x01 << address) & lock)) // locked blocks
+ break;
+
+ // FIXME: Test dynamic lock bytes
+
+ memory.replace(address * 8, 8, data);
+
+ response.append(address);
+ response.append(memory.mid(address * 8, 8));
+ break;
+ }
+ case 0x1b: // WRITE-NE8
+ // locked blocks
+ if (address == 0x00 || address == 0x0d || address == 0x0e || address == 0x0f)
+ break;
+
+ quint16 lock = (readData(0x0e, 0x01) << 8) | readData(0x0e, 0x00);
+ if (address <= 0x0e && ((0x01 << address) & lock)) // locked blocks
+ break;
+
+ // FIXME: Test dynamic lock bytes
+
+ for (int i = 0; i < 8; ++i)
+ memory[address * 8 + i] = memory.at(address * 8 + i) | data.at(i);
+
+ response.append(address);
+ response.append(memory.mid(address * 8, 8));
+ break;
+ }
+ }
+
+ if (!response.isEmpty()) {
+ quint16 crc = qNfcChecksum(response.constData(), response.length());
+ response.append(quint8(crc & 0xff));
+ response.append(quint8(crc >> 8));
+ }
+
+ return response;
+}
+
+
+NfcTagType2::NfcTagType2()
+: memory(64, 0x00), currentSector(0), expectPacket2(false)
+{
+}
+
+void NfcTagType2::load(QSettings *settings)
+{
+ settings->beginGroup(QLatin1String("TagType2"));
+
+ memory = settings->value(QLatin1String("Data")).toByteArray();
+
+ settings->endGroup();
+}
+
+QByteArray NfcTagType2::uid() const
+{
+ lastAccess = QDateTime::currentMSecsSinceEpoch();
+
+ return memory.left(3) + memory.mid(4, 4);
+}
+
+#define NACK QByteArray("\x05")
+#define ACK QByteArray("\x0a")
+
+QByteArray NfcTagType2::processCommand(const QByteArray &command)
+{
+ lastAccess = QDateTime::currentMSecsSinceEpoch();
+
+ QByteArray response;
+
+ // check checksum
+ if (qNfcChecksum(command.constData(), command.length()) != 0)
+ return QByteArray();
+
+ if (expectPacket2) {
+ expectPacket2 = false;
+ quint8 sector = command.at(0);
+ if (sector * 1024 > memory.length())
+ return NACK;
+ else {
+ currentSector = sector;
+ return QByteArray();
+ }
+ }
+
+ quint8 opcode = command.at(0);
+
+ switch (opcode) {
+ case 0x30: { // READ BLOCK
+ quint8 block = command.at(1);
+ int absoluteBlock = currentSector * 256 + block;
+
+ response.append(memory.mid(absoluteBlock * 4, 16));
+ if (response.length() != 16)
+ response.append(QByteArray(16 - response.length(), '\0'));
+
+ break;
+ }
+ case 0xa2: { // WRITE BLOCK
+ quint8 block = command.at(1);
+ int absoluteBlock = currentSector * 256 + block;
+
+ // locked blocks
+ if (absoluteBlock == 0 || absoluteBlock == 1)
+ return NACK;
+
+ const QByteArray data = command.mid(2, 4);
+
+ memory.replace(absoluteBlock * 4, 4, data);
+
+ return ACK;
+ }
+ case 0xc2: // SECTOR SELECT - Packet 1
+ if (memory.length() > 1024) {
+ expectPacket2 = true;
+ return ACK;
+ }
+
+ return NACK;
+ default:
+ qDebug() << "Unknown opcode for Tag Type 2" << hex << opcode;
+ qDebug() << "command:" << command.toHex();
+
+ return NACK;
+ ;
+ }
+
+ if (!response.isEmpty()) {
+ quint16 crc = qNfcChecksum(response.constData(), response.length());
+ response.append(quint8(crc & 0xff));
+ response.append(quint8(crc >> 8));
+ }
+
+ return response;
+}
diff --git a/src/nfc/targetemulator_p.h b/src/nfc/targetemulator_p.h
new file mode 100644
index 00000000..a19dd17d
--- /dev/null
+++ b/src/nfc/targetemulator_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TARGETEMULATOR_P_H
+#define TARGETEMULATOR_P_H
+
+#include <QtCore/QtGlobal>
+#include <QtCore/QByteArray>
+
+QT_FORWARD_DECLARE_CLASS(QSettings)
+
+class TagBase
+{
+public:
+ TagBase();
+ ~TagBase();
+
+ virtual void load(QSettings *settings) = 0;
+
+ virtual QByteArray processCommand(const QByteArray &command) = 0;
+
+ virtual QByteArray uid() const = 0;
+
+ qint64 lastAccessTime() const { return lastAccess; }
+
+protected:
+ mutable qint64 lastAccess;
+};
+
+class NfcTagType1 : public TagBase
+{
+public:
+ NfcTagType1();
+ ~NfcTagType1();
+
+ void load(QSettings *settings);
+
+ QByteArray processCommand(const QByteArray &command);
+
+ QByteArray uid() const;
+
+private:
+ quint8 readData(quint8 block, quint8 byte);
+
+ quint8 hr0;
+ quint8 hr1;
+
+ QByteArray memory;
+};
+
+class NfcTagType2 : public TagBase
+{
+public:
+ NfcTagType2();
+ ~NfcTagType2();
+
+ void load(QSettings *settings);
+
+ QByteArray processCommand(const QByteArray &command);
+
+ QByteArray uid() const;
+
+private:
+ QByteArray memory;
+ quint8 currentSector;
+ bool expectPacket2;
+};
+
+#endif // TARGETEMULATOR_P_H