1// Copyright (C) 2016 BlackBerry Limited, Copyright (C) 2016 BasysKom GmbH
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qnearfieldmanager_neard_p.h"
5#include "qnearfieldtarget_neard_p.h"
6
7#include "adapter_interface.h"
8#include "properties_interface.h"
9#include "objectmanager_interface.h"
10
11QT_BEGIN_NAMESPACE
12
13Q_DECLARE_LOGGING_CATEGORY(QT_NFC_NEARD)
14Q_LOGGING_CATEGORY(QT_NFC_NEARD, "qt.nfc.neard")
15
16// TODO We need a constructor that lets us select an adapter
17QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
18 : QNearFieldManagerPrivate(),
19 m_neardHelper(NeardHelper::instance())
20{
21 QDBusPendingReply<ManagedObjectList> reply = m_neardHelper->dbusObjectManager()->GetManagedObjects();
22 reply.waitForFinished();
23 if (reply.isError()) {
24 qCWarning(QT_NFC_NEARD) << "Error getting managed objects";
25 return;
26 }
27
28 bool found = false;
29 const QList<QDBusObjectPath> paths = reply.value().keys();
30 for (const QDBusObjectPath &path : paths) {
31 const InterfaceList ifaceList = reply.value().value(path);
32 const QStringList ifaces = ifaceList.keys();
33 for (const QString &iface : ifaces) {
34 if (iface == QStringLiteral("org.neard.Adapter")) {
35 found = true;
36 m_adapterPath = path.path();
37 qCDebug(QT_NFC_NEARD) << "org.neard.Adapter found for path" << m_adapterPath;
38 break;
39 }
40 }
41
42 if (found)
43 break;
44 }
45
46 if (!found) {
47 qCWarning(QT_NFC_NEARD) << "no adapter found, neard daemon running?";
48 } else {
49 connect(m_neardHelper, &NeardHelper::tagFound,
50 this, &QNearFieldManagerPrivateImpl::handleTagFound);
51 connect(m_neardHelper, &NeardHelper::tagRemoved,
52 this, &QNearFieldManagerPrivateImpl::handleTagRemoved);
53 }
54}
55
56QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl()
57{
58 stopTargetDetection();
59}
60
61bool QNearFieldManagerPrivateImpl::isEnabled() const
62{
63 if (!m_neardHelper->dbusObjectManager()->isValid() || m_adapterPath.isNull()) {
64 qCWarning(QT_NFC_NEARD) << "dbus object manager invalid or adapter path invalid";
65 return false;
66 }
67
68 QDBusPendingReply<ManagedObjectList> reply = m_neardHelper->dbusObjectManager()->GetManagedObjects();
69 reply.waitForFinished();
70 if (reply.isError()) {
71 qCWarning(QT_NFC_NEARD) << "error getting managed objects";
72 return false;
73 }
74
75 const QList<QDBusObjectPath> paths = reply.value().keys();
76 for (const QDBusObjectPath &path : paths) {
77 if (m_adapterPath == path.path())
78 return true;
79 }
80
81 return false;
82}
83
84bool QNearFieldManagerPrivateImpl::isSupported(QNearFieldTarget::AccessMethod accessMethod) const
85{
86 if (m_adapterPath.isEmpty()) {
87 qCWarning(QT_NFC_NEARD) << "no adapter found, neard daemon running?";
88 return false;
89 }
90
91 if (!m_neardHelper->dbusObjectManager()->isValid()) {
92 qCWarning(QT_NFC_NEARD) << "dbus object manager invalid or adapter path invalid";
93 return false;
94 }
95
96 return accessMethod == QNearFieldTarget::NdefAccess;
97}
98
99bool QNearFieldManagerPrivateImpl::startTargetDetection(QNearFieldTarget::AccessMethod accessMethod)
100{
101 qCDebug(QT_NFC_NEARD) << "starting target detection";
102 if (!isEnabled() || accessMethod != QNearFieldTarget::NdefAccess)
103 return false;
104
105 OrgFreedesktopDBusPropertiesInterface dbusProperties(QStringLiteral("org.neard"),
106 m_adapterPath,
107 QDBusConnection::systemBus());
108
109 if (!dbusProperties.isValid()) {
110 qCWarning(QT_NFC_NEARD) << "dbus property interface invalid";
111 return false;
112 }
113
114 // check if the adapter is currently polling
115 QDBusPendingReply<QDBusVariant> replyPolling = dbusProperties.Get(QStringLiteral("org.neard.Adapter"),
116 QStringLiteral("Polling"));
117 replyPolling.waitForFinished();
118 if (!replyPolling.isError()) {
119 if (replyPolling.value().variant().toBool()) {
120 qCDebug(QT_NFC_NEARD) << "adapter is already polling";
121 return true;
122 }
123 } else {
124 qCWarning(QT_NFC_NEARD) << "error getting 'Polling' state from property interface";
125 return false;
126 }
127
128 // check if the adapter it powered
129 QDBusPendingReply<QDBusVariant> replyPowered = dbusProperties.Get(QStringLiteral("org.neard.Adapter"),
130 QStringLiteral("Powered"));
131 replyPowered.waitForFinished();
132 if (!replyPowered.isError()) {
133 if (replyPowered.value().variant().toBool()) {
134 qCDebug(QT_NFC_NEARD) << "adapter is already powered";
135 } else {
136 QDBusPendingReply<QDBusVariant> replyTryPowering = dbusProperties.Set(QStringLiteral("org.neard.Adapter"),
137 QStringLiteral("Powered"),
138 QDBusVariant(true));
139 replyTryPowering.waitForFinished();
140 if (!replyTryPowering.isError()) {
141 qCDebug(QT_NFC_NEARD) << "powering adapter";
142 }
143 }
144 } else {
145 qCWarning(QT_NFC_NEARD) << "error getting 'Powered' state from property interface";
146 return false;
147 }
148
149 // create adapter and start poll loop
150 OrgNeardAdapterInterface neardAdapter(QStringLiteral("org.neard"),
151 m_adapterPath,
152 QDBusConnection::systemBus());
153
154 // possible modes: "Target", "Initiator", "Dual"
155 QDBusPendingReply<> replyPollLoop = neardAdapter.StartPollLoop(QStringLiteral("Initiator"));
156 replyPollLoop.waitForFinished();
157 if (replyPollLoop.isError()) {
158 qCWarning(QT_NFC_NEARD) << "error when starting polling";
159 return false;
160 } else {
161 qCDebug(QT_NFC_NEARD) << "successfully started polling";
162 }
163
164 return true;
165}
166
167void QNearFieldManagerPrivateImpl::stopTargetDetection(const QString&)
168{
169 qCDebug(QT_NFC_NEARD) << "stopping target detection";
170 if (!isEnabled())
171 return;
172
173 OrgFreedesktopDBusPropertiesInterface dbusProperties(QStringLiteral("org.neard"),
174 m_adapterPath,
175 QDBusConnection::systemBus());
176
177 if (!dbusProperties.isValid()) {
178 qCWarning(QT_NFC_NEARD) << "dbus property interface invalid";
179 return;
180 }
181
182 // check if the adapter is currently polling
183 QDBusPendingReply<QDBusVariant> replyPolling = dbusProperties.Get(QStringLiteral("org.neard.Adapter"),
184 QStringLiteral("Polling"));
185 replyPolling.waitForFinished();
186 if (!replyPolling.isError()) {
187 if (replyPolling.value().variant().toBool()) {
188 // create adapter and stop poll loop
189 OrgNeardAdapterInterface neardAdapter(QStringLiteral("org.neard"),
190 m_adapterPath,
191 QDBusConnection::systemBus());
192
193 QDBusPendingReply<> replyStopPolling = neardAdapter.StopPollLoop();
194 replyStopPolling.waitForFinished();
195 if (replyStopPolling.isError())
196 qCWarning(QT_NFC_NEARD) << "error when stopping polling";
197 else
198 qCDebug(QT_NFC_NEARD) << "successfully stopped polling";
199 } else {
200 qCDebug(QT_NFC_NEARD) << "already stopped polling";
201 }
202 } else {
203 qCWarning(QT_NFC_NEARD) << "error getting 'Polling' state from property interface";
204 }
205}
206
207void QNearFieldManagerPrivateImpl::handleTagFound(const QDBusObjectPath &path)
208{
209 auto priv = new QNearFieldTargetPrivateImpl(this, path);
210 auto nfTag = new QNearFieldTarget(priv, this);
211 m_activeTags.insert(path.path(), nfTag);
212 emit targetDetected(target: nfTag);
213}
214
215void QNearFieldManagerPrivateImpl::handleTagRemoved(const QDBusObjectPath &path)
216{
217 const QString adapterPath = path.path();
218 if (m_activeTags.contains(key: adapterPath)) {
219 QNearFieldTarget *nfTag = m_activeTags.value(key: adapterPath);
220 m_activeTags.remove(key: adapterPath);
221 emit targetLost(target: nfTag);
222 }
223}
224
225QT_END_NAMESPACE
226

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtconnectivity/src/nfc/qnearfieldmanager_neard.cpp