ModemManagerQt

manager.cpp
1/*
2 SPDX-FileCopyrightText: 2008, 2011 Will Stephenson <wstephenson@kde.org>
3 SPDX-FileCopyrightText: 2010 Lamarque Souza <lamarque@kde.org>
4 SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com>
5 SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com>
6 SPDX-FileCopyrightText: 2013-2015 Jan Grulich <jgrulich@redhat.com>
7
8 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
9*/
10
11#include "manager.h"
12#include "manager_p.h"
13
14#ifdef MMQT_STATIC
15#include "dbus/fakedbus.h"
16#else
17#include "dbus/dbus.h"
18#endif
19#include "generictypes.h"
20#include "generictypes_p.h"
21#include "macros_p.h"
22#include "mmdebug_p.h"
23#include "modem.h"
24
25#include <QDBusConnectionInterface>
26#include <QDBusMetaType>
27#include <QDBusReply>
28
29Q_GLOBAL_STATIC(ModemManager::ModemManagerPrivate, globalModemManager)
30
31ModemManager::ModemManagerPrivate::ModemManagerPrivate()
32#ifdef MMQT_STATIC
33 : watcher(QLatin1String(MMQT_DBUS_SERVICE),
36 this)
37 , iface(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::sessionBus(), this)
38 , manager(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::sessionBus(), this)
39#else
40 : watcher(QLatin1String(MMQT_DBUS_SERVICE),
43 this)
44 , iface(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::systemBus(), this)
45 , manager(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::systemBus(), this)
46#endif
47{
48 qDBusRegisterMetaType<QList<QDBusObjectPath>>();
49 registerModemManagerTypes();
50
51 bool serviceFound = manager.isValid();
52 if (!serviceFound) {
53 // find out whether it will be activated automatically
54 QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"),
55 QStringLiteral("/org/freedesktop/DBus"),
56 QStringLiteral("org.freedesktop.DBus"),
57 QStringLiteral("ListActivatableNames"));
58#ifdef MMQT_STATIC
60 if (reply.isValid() && reply.value().contains(QLatin1String(MMQT_DBUS_SERVICE))) {
62 serviceFound = true;
63 }
64 }
65#else
67 if (reply.isValid() && reply.value().contains(QLatin1String(MMQT_DBUS_SERVICE))) {
69 serviceFound = true;
70 }
71 }
72#endif
73
74 if (serviceFound) {
75 connect(&manager, &OrgFreedesktopDBusObjectManagerInterface::InterfacesAdded, this, &ModemManagerPrivate::onInterfacesAdded);
76 connect(&manager, &OrgFreedesktopDBusObjectManagerInterface::InterfacesRemoved, this, &ModemManagerPrivate::onInterfacesRemoved);
77 }
78
79 connect(&watcher, &QDBusServiceWatcher::serviceRegistered, this, &ModemManagerPrivate::daemonRegistered);
80 connect(&watcher, &QDBusServiceWatcher::serviceUnregistered, this, &ModemManagerPrivate::daemonUnregistered);
81
82 init();
83}
84
85ModemManager::ModemManagerPrivate::~ModemManagerPrivate()
86{
87}
88
89void ModemManager::ModemManagerPrivate::init()
90{
91 modemList.clear();
92
93 QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects();
94 reply.waitForFinished();
95 if (!reply.isError()) { // enum devices
96 Q_FOREACH (const QDBusObjectPath &path, reply.value().keys()) {
97 const QString uni = path.path();
98 qCDebug(MMQT) << "Adding device" << uni;
99
100 if (uni == QLatin1String(MMQT_DBUS_PATH) || !uni.startsWith(QLatin1String(MMQT_DBUS_MODEM_PREFIX))) {
101 continue;
102 }
103
104 modemList.insert(uni, ModemDevice::Ptr());
105 Q_EMIT modemAdded(uni);
106 }
107 } else { // show error
108 qCWarning(MMQT) << "Failed enumerating MM objects:" << reply.error().name() << "\n" << reply.error().message();
109 }
110}
111
112ModemManager::ModemDevice::Ptr ModemManager::ModemManagerPrivate::findModemDevice(const QString &uni)
113{
114 ModemDevice::Ptr modem;
115 if (modemList.contains(uni)) {
116 if (modemList.value(uni)) {
117 modem = modemList.value(uni);
118 } else {
119 modem = ModemDevice::Ptr(new ModemDevice(uni), &QObject::deleteLater);
120 modemList[uni] = modem;
121 }
122 }
123 return modem;
124}
125
126ModemManager::ModemDevice::List ModemManager::ModemManagerPrivate::modemDevices()
127{
129
131 for (i = modemList.constBegin(); i != modemList.constEnd(); ++i) {
132 ModemDevice::Ptr modem = findModemDevice(i.key());
133 if (!modem.isNull()) {
134 list.append(modem);
135 } else {
136 qCWarning(MMQT) << "warning: null modem Interface for" << i.key();
137 }
138 }
139
140 return list;
141}
142
143void ModemManager::ModemManagerPrivate::scanDevices()
144{
145 iface.ScanDevices();
146}
147
148void ModemManager::ModemManagerPrivate::daemonRegistered()
149{
150 init();
151 Q_EMIT serviceAppeared();
152}
153
154void ModemManager::ModemManagerPrivate::daemonUnregistered()
155{
156 Q_EMIT serviceDisappeared();
157 modemList.clear();
158}
159
160void ModemManager::ModemManagerPrivate::onInterfacesAdded(const QDBusObjectPath &object_path, const MMVariantMapMap &interfaces_and_properties)
161{
162 // TODO control added bearers and sim cards
163
164 const QString uni = object_path.path();
165
166 /* Ignore non-modems */
167 if (!uni.startsWith(QLatin1String(MMQT_DBUS_MODEM_PREFIX))) {
168 return;
169 }
170
171 qCDebug(MMQT) << uni << "has new interfaces:" << interfaces_and_properties.keys();
172
173 // new device, we don't know it yet
174 if (!modemList.contains(uni)) {
175 modemList.insert(uni, ModemDevice::Ptr());
176 Q_EMIT modemAdded(uni);
177 }
178 // re-Q_EMIT in case of modem type change (GSM <-> CDMA)
179 else if (modemList.contains(uni)
180 && (interfaces_and_properties.keys().contains(QLatin1String(MMQT_DBUS_INTERFACE_MODEM_MODEM3GPP))
181 || interfaces_and_properties.keys().contains(QLatin1String(MMQT_DBUS_INTERFACE_MODEM_MODEMCDMA)))) {
182 Q_EMIT modemAdded(uni);
183 }
184}
185
186void ModemManager::ModemManagerPrivate::onInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces)
187{
188 // TODO control removed bearers and sim cards
189
190 const QString uni = object_path.path();
191
192 /* Ignore non-modems */
193 if (!uni.startsWith(QLatin1String(MMQT_DBUS_MODEM_PREFIX))) {
194 return;
195 }
196
197 qCDebug(MMQT) << uni << "lost interfaces:" << interfaces;
198
199 ModemDevice::Ptr modem = findModemDevice(uni);
200
201 // Remove modem when there is no interface or Modem interfaces has been removed
202 if (!uni.isEmpty() && (interfaces.isEmpty() || (modem && modem->interfaces().isEmpty()) || interfaces.contains(QLatin1String(MMQT_DBUS_INTERFACE_MODEM)))) {
203 Q_EMIT modemRemoved(uni);
204 modemList.remove(uni);
205 }
206}
207
209{
210 return globalModemManager->findModemDevice(uni);
211}
212
214{
215 return globalModemManager->modemDevices();
216}
217
218ModemManager::Notifier *ModemManager::notifier()
219{
220 return globalModemManager;
221}
222
224{
225 globalModemManager->scanDevices();
226}
227
228#include "moc_manager.cpp"
229#include "moc_manager_p.cpp"
QString path(const QString &relativePath)
MODEMMANAGERQT_EXPORT void scanDevices()
Start a new scan for connected modem devices.
Definition manager.cpp:143
MODEMMANAGERQT_EXPORT ModemDevice::List modemDevices()
Retrieves the list of all modem interfaces Unique Device Identifiers (UDIs) in the system.
Definition manager.cpp:126
MODEMMANAGERQT_EXPORT ModemDevice::Ptr findModemDevice(const QString &uni)
Find a new ModemManagerInterface object given its UDI.
Definition manager.cpp:112
QCA_EXPORT void init()
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const const
QDBusConnectionInterface * interface() const const
QDBusConnection sessionBus()
QDBusConnection systemBus()
QDBusReply< void > startService(const QString &name)
QString message() const const
QString name() const const
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
QString path() const const
QDBusError error() const const
bool isError() const const
typename Select< 0 >::Type value() const const
bool isValid() const const
void serviceRegistered(const QString &serviceName)
void serviceUnregistered(const QString &serviceName)
void append(QList< T > &&value)
void deleteLater()
bool isNull() const const
QString & insert(qsizetype position, QChar ch)
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:51 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.