summaryrefslogtreecommitdiffstats
path: root/src/nfc/qnearfieldmanager_neard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/nfc/qnearfieldmanager_neard.cpp')
-rw-r--r--src/nfc/qnearfieldmanager_neard.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/nfc/qnearfieldmanager_neard.cpp b/src/nfc/qnearfieldmanager_neard.cpp
new file mode 100644
index 00000000..389d701e
--- /dev/null
+++ b/src/nfc/qnearfieldmanager_neard.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2014 BasysKom GmbH.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNfc module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnearfieldmanager_neard_p.h"
+#include "qnearfieldtarget_neard_p.h"
+
+#include "neard/adapter_p.h"
+#include "neard/dbusproperties_p.h"
+#include "neard/dbusobjectmanager_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_NFC_NEARD)
+
+// TODO We need a constructor that lets us select an adapter
+QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
+ : QNearFieldManagerPrivate(),
+ m_neardHelper(NeardHelper::instance())
+{
+ QDBusPendingReply<ManagedObjectList> reply = m_neardHelper->dbusObjectManager()->GetManagedObjects();
+ reply.waitForFinished();
+ if (reply.isError()) {
+ qCWarning(QT_NFC_NEARD) << "Error getting managed objects";
+ return;
+ }
+
+ bool found = false;
+ foreach (const QDBusObjectPath &path, reply.value().keys()) {
+ const InterfaceList ifaceList = reply.value().value(path);
+ foreach (const QString &iface, ifaceList.keys()) {
+ if (iface == QStringLiteral("org.neard.Adapter")) {
+ found = true;
+ m_adapterPath = path.path();
+ qCDebug(QT_NFC_NEARD) << "org.neard.Adapter found for path" << m_adapterPath;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (!found) {
+ qCWarning(QT_NFC_NEARD) << "no adapter found, neard daemon running?";
+ } else {
+ connect(m_neardHelper, SIGNAL(tagFound(QDBusObjectPath)),
+ this, SLOT(handleTagFound(QDBusObjectPath)));
+ connect(m_neardHelper, SIGNAL(tagRemoved(QDBusObjectPath)),
+ this, SLOT(handleTagRemoved(QDBusObjectPath)));
+ }
+}
+
+QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
+{
+ stopTargetDetection();
+}
+
+bool QNearFieldManagerPrivateImpl::isAvailable() const
+{
+ if (!m_neardHelper->dbusObjectManager()->isValid() || m_adapterPath.isNull()) {
+ qCWarning(QT_NFC_NEARD) << "dbus object manager invalid or adapter path invalid";
+ return false;
+ }
+
+ QDBusPendingReply<ManagedObjectList> reply = m_neardHelper->dbusObjectManager()->GetManagedObjects();
+ reply.waitForFinished();
+ if (reply.isError()) {
+ qCWarning(QT_NFC_NEARD) << "error getting managed objects";
+ return false;
+ }
+
+ foreach (const QDBusObjectPath &path, reply.value().keys()) {
+ if (m_adapterPath == path.path())
+ return true;
+ }
+
+ return false;
+}
+
+bool QNearFieldManagerPrivateImpl::startTargetDetection()
+{
+ qCDebug(QT_NFC_NEARD) << "starting target detection";
+ if (!isAvailable())
+ return false;
+
+ OrgFreedesktopDBusPropertiesInterface dbusProperties(QStringLiteral("org.neard"),
+ m_adapterPath,
+ QDBusConnection::systemBus());
+
+ if (!dbusProperties.isValid()) {
+ qCWarning(QT_NFC_NEARD) << "dbus property interface invalid";
+ return false;
+ }
+
+ // check if the adapter is currently polling
+ QDBusPendingReply<QDBusVariant> replyPolling = dbusProperties.Get(QStringLiteral("org.neard.Adapter"),
+ QStringLiteral("Polling"));
+ replyPolling.waitForFinished();
+ if (!replyPolling.isError()) {
+ if (replyPolling.value().variant().toBool()) {
+ qCDebug(QT_NFC_NEARD) << "adapter is already polling";
+ return true;
+ }
+ } else {
+ qCWarning(QT_NFC_NEARD) << "error getting 'Polling' state from property interface";
+ return false;
+ }
+
+ // check if the adapter it powered
+ QDBusPendingReply<QDBusVariant> replyPowered = dbusProperties.Get(QStringLiteral("org.neard.Adapter"),
+ QStringLiteral("Powered"));
+ replyPowered.waitForFinished();
+ if (!replyPowered.isError()) {
+ if (replyPowered.value().variant().toBool()) {
+ qCDebug(QT_NFC_NEARD) << "adapter is already powered";
+ } else {
+ QDBusPendingReply<QDBusVariant> replyTryPowering = dbusProperties.Set(QStringLiteral("org.neard.Adapter"),
+ QStringLiteral("Powered"),
+ QDBusVariant(true));
+ replyTryPowering.waitForFinished();
+ if (!replyTryPowering.isError()) {
+ qCDebug(QT_NFC_NEARD) << "powering adapter";
+ }
+ }
+ } else {
+ qCWarning(QT_NFC_NEARD) << "error getting 'Powered' state from property interface";
+ return false;
+ }
+
+ // create adapter and start poll loop
+ OrgNeardAdapterInterface neardAdapter(QStringLiteral("org.neard"),
+ m_adapterPath,
+ QDBusConnection::systemBus());
+
+ // possible modes: "Target", "Initiator", "Dual"
+ QDBusPendingReply<> replyPollLoop = neardAdapter.StartPollLoop(QStringLiteral("Dual"));
+ replyPollLoop.waitForFinished();
+ if (replyPollLoop.isError()) {
+ qCWarning(QT_NFC_NEARD) << "error when starting polling";
+ return false;
+ } else {
+ qCDebug(QT_NFC_NEARD) << "successfully started polling";
+ }
+
+ return true;
+}
+
+void QNearFieldManagerPrivateImpl::stopTargetDetection()
+{
+ qCDebug(QT_NFC_NEARD) << "stopping target detection";
+ if (!isAvailable())
+ return;
+
+ OrgFreedesktopDBusPropertiesInterface dbusProperties(QStringLiteral("org.neard"),
+ m_adapterPath,
+ QDBusConnection::systemBus());
+
+ if (!dbusProperties.isValid()) {
+ qCWarning(QT_NFC_NEARD) << "dbus property interface invalid";
+ return;
+ }
+
+ // check if the adapter is currently polling
+ QDBusPendingReply<QDBusVariant> replyPolling = dbusProperties.Get(QStringLiteral("org.neard.Adapter"),
+ QStringLiteral("Polling"));
+ replyPolling.waitForFinished();
+ if (!replyPolling.isError()) {
+ if (replyPolling.value().variant().toBool()) {
+ // create adapter and stop poll loop
+ OrgNeardAdapterInterface neardAdapter(QStringLiteral("org.neard"),
+ m_adapterPath,
+ QDBusConnection::systemBus());
+
+ QDBusPendingReply<> replyStopPolling = neardAdapter.StopPollLoop();
+ replyStopPolling.waitForFinished();
+ if (replyStopPolling.isError())
+ qCWarning(QT_NFC_NEARD) << "error when stopping polling";
+ else
+ qCDebug(QT_NFC_NEARD) << "successfully stopped polling";
+ } else {
+ qCDebug(QT_NFC_NEARD) << "already stopped polling";
+ }
+ } else {
+ qCWarning(QT_NFC_NEARD) << "error getting 'Polling' state from property interface";
+ }
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(QObject *object, const QMetaMethod &method)
+{
+ Q_UNUSED(object);
+ Q_UNUSED(method);
+ return -1;
+}
+
+int QNearFieldManagerPrivateImpl::registerNdefMessageHandler(const QNdefFilter &filter, QObject *object, const QMetaMethod &method)
+{
+ Q_UNUSED(filter);
+ Q_UNUSED(object);
+ Q_UNUSED(method);
+ return -1;
+}
+
+bool QNearFieldManagerPrivateImpl::unregisterNdefMessageHandler(int handlerId)
+{
+ Q_UNUSED(handlerId);
+ return false;
+}
+
+void QNearFieldManagerPrivateImpl::requestAccess(QNearFieldManager::TargetAccessModes accessModes)
+{
+ Q_UNUSED(accessModes);
+}
+
+void QNearFieldManagerPrivateImpl::releaseAccess(QNearFieldManager::TargetAccessModes accessModes)
+{
+ Q_UNUSED(accessModes);
+}
+
+void QNearFieldManagerPrivateImpl::handleTagFound(const QDBusObjectPath &path)
+{
+ NearFieldTarget<QNearFieldTarget> *nfTag = new NearFieldTarget<QNearFieldTarget>(this, path);
+ m_activeTags.insert(path.path(), nfTag);
+ emit targetDetected(nfTag);
+}
+
+void QNearFieldManagerPrivateImpl::handleTagRemoved(const QDBusObjectPath &path)
+{
+ const QString adapterPath = path.path();
+ if (m_activeTags.contains(adapterPath)) {
+ QNearFieldTarget *nfTag = m_activeTags.value(adapterPath);
+ m_activeTags.remove(adapterPath);
+ emit targetLost(nfTag);
+ }
+}
+
+QT_END_NAMESPACE