File indexing completed on 2025-03-23 06:52:21
0001 /* 0002 SPDX-FileCopyrightText: 2008, 2011 Will Stephenson <wstephenson@kde.org> 0003 SPDX-FileCopyrightText: 2010 Lamarque Souza <lamarque@kde.org> 0004 SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com> 0005 SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com> 0006 SPDX-FileCopyrightText: 2013-2015 Jan Grulich <jgrulich@redhat.com> 0007 0008 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0009 */ 0010 0011 #include "manager.h" 0012 #include "manager_p.h" 0013 0014 #ifdef MMQT_STATIC 0015 #include "dbus/fakedbus.h" 0016 #else 0017 #include "dbus/dbus.h" 0018 #endif 0019 #include "generictypes.h" 0020 #include "generictypes_p.h" 0021 #include "macros_p.h" 0022 #include "mmdebug_p.h" 0023 #include "modem.h" 0024 0025 #include <QDBusConnectionInterface> 0026 #include <QDBusMetaType> 0027 #include <QDBusReply> 0028 0029 Q_GLOBAL_STATIC(ModemManager::ModemManagerPrivate, globalModemManager) 0030 0031 ModemManager::ModemManagerPrivate::ModemManagerPrivate() 0032 #ifdef MMQT_STATIC 0033 : watcher(QLatin1String(MMQT_DBUS_SERVICE), 0034 QDBusConnection::sessionBus(), 0035 QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, 0036 this) 0037 , iface(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::sessionBus(), this) 0038 , manager(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::sessionBus(), this) 0039 #else 0040 : watcher(QLatin1String(MMQT_DBUS_SERVICE), 0041 QDBusConnection::systemBus(), 0042 QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, 0043 this) 0044 , iface(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::systemBus(), this) 0045 , manager(QLatin1String(MMQT_DBUS_SERVICE), QLatin1String(MMQT_DBUS_PATH), QDBusConnection::systemBus(), this) 0046 #endif 0047 { 0048 qDBusRegisterMetaType<QList<QDBusObjectPath>>(); 0049 registerModemManagerTypes(); 0050 0051 bool serviceFound = manager.isValid(); 0052 if (!serviceFound) { 0053 // find out whether it will be activated automatically 0054 QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"), 0055 QStringLiteral("/org/freedesktop/DBus"), 0056 QStringLiteral("org.freedesktop.DBus"), 0057 QStringLiteral("ListActivatableNames")); 0058 #ifdef MMQT_STATIC 0059 QDBusReply<QStringList> reply = QDBusConnection::sessionBus().call(message); 0060 if (reply.isValid() && reply.value().contains(QLatin1String(MMQT_DBUS_SERVICE))) { 0061 QDBusConnection::sessionBus().interface()->startService(QLatin1String(MMQT_DBUS_SERVICE)); 0062 serviceFound = true; 0063 } 0064 } 0065 #else 0066 QDBusReply<QStringList> reply = QDBusConnection::systemBus().call(message); 0067 if (reply.isValid() && reply.value().contains(QLatin1String(MMQT_DBUS_SERVICE))) { 0068 QDBusConnection::systemBus().interface()->startService(QLatin1String(MMQT_DBUS_SERVICE)); 0069 serviceFound = true; 0070 } 0071 } 0072 #endif 0073 0074 if (serviceFound) { 0075 connect(&manager, &OrgFreedesktopDBusObjectManagerInterface::InterfacesAdded, this, &ModemManagerPrivate::onInterfacesAdded); 0076 connect(&manager, &OrgFreedesktopDBusObjectManagerInterface::InterfacesRemoved, this, &ModemManagerPrivate::onInterfacesRemoved); 0077 } 0078 0079 connect(&watcher, &QDBusServiceWatcher::serviceRegistered, this, &ModemManagerPrivate::daemonRegistered); 0080 connect(&watcher, &QDBusServiceWatcher::serviceUnregistered, this, &ModemManagerPrivate::daemonUnregistered); 0081 0082 init(); 0083 } 0084 0085 ModemManager::ModemManagerPrivate::~ModemManagerPrivate() 0086 { 0087 } 0088 0089 void ModemManager::ModemManagerPrivate::init() 0090 { 0091 modemList.clear(); 0092 0093 QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects(); 0094 reply.waitForFinished(); 0095 if (!reply.isError()) { // enum devices 0096 Q_FOREACH (const QDBusObjectPath &path, reply.value().keys()) { 0097 const QString uni = path.path(); 0098 qCDebug(MMQT) << "Adding device" << uni; 0099 0100 if (uni == QLatin1String(MMQT_DBUS_PATH) || !uni.startsWith(QLatin1String(MMQT_DBUS_MODEM_PREFIX))) { 0101 continue; 0102 } 0103 0104 modemList.insert(uni, ModemDevice::Ptr()); 0105 Q_EMIT modemAdded(uni); 0106 } 0107 } else { // show error 0108 qCWarning(MMQT) << "Failed enumerating MM objects:" << reply.error().name() << "\n" << reply.error().message(); 0109 } 0110 } 0111 0112 ModemManager::ModemDevice::Ptr ModemManager::ModemManagerPrivate::findModemDevice(const QString &uni) 0113 { 0114 ModemDevice::Ptr modem; 0115 if (modemList.contains(uni)) { 0116 if (modemList.value(uni)) { 0117 modem = modemList.value(uni); 0118 } else { 0119 modem = ModemDevice::Ptr(new ModemDevice(uni), &QObject::deleteLater); 0120 modemList[uni] = modem; 0121 } 0122 } 0123 return modem; 0124 } 0125 0126 ModemManager::ModemDevice::List ModemManager::ModemManagerPrivate::modemDevices() 0127 { 0128 ModemDevice::List list; 0129 0130 QMap<QString, ModemDevice::Ptr>::const_iterator i; 0131 for (i = modemList.constBegin(); i != modemList.constEnd(); ++i) { 0132 ModemDevice::Ptr modem = findModemDevice(i.key()); 0133 if (!modem.isNull()) { 0134 list.append(modem); 0135 } else { 0136 qCWarning(MMQT) << "warning: null modem Interface for" << i.key(); 0137 } 0138 } 0139 0140 return list; 0141 } 0142 0143 void ModemManager::ModemManagerPrivate::scanDevices() 0144 { 0145 iface.ScanDevices(); 0146 } 0147 0148 void ModemManager::ModemManagerPrivate::daemonRegistered() 0149 { 0150 init(); 0151 Q_EMIT serviceAppeared(); 0152 } 0153 0154 void ModemManager::ModemManagerPrivate::daemonUnregistered() 0155 { 0156 Q_EMIT serviceDisappeared(); 0157 modemList.clear(); 0158 } 0159 0160 void ModemManager::ModemManagerPrivate::onInterfacesAdded(const QDBusObjectPath &object_path, const MMVariantMapMap &interfaces_and_properties) 0161 { 0162 // TODO control added bearers and sim cards 0163 0164 const QString uni = object_path.path(); 0165 0166 /* Ignore non-modems */ 0167 if (!uni.startsWith(QLatin1String(MMQT_DBUS_MODEM_PREFIX))) { 0168 return; 0169 } 0170 0171 qCDebug(MMQT) << uni << "has new interfaces:" << interfaces_and_properties.keys(); 0172 0173 // new device, we don't know it yet 0174 if (!modemList.contains(uni)) { 0175 modemList.insert(uni, ModemDevice::Ptr()); 0176 Q_EMIT modemAdded(uni); 0177 } 0178 // re-Q_EMIT in case of modem type change (GSM <-> CDMA) 0179 else if (modemList.contains(uni) 0180 && (interfaces_and_properties.keys().contains(QLatin1String(MMQT_DBUS_INTERFACE_MODEM_MODEM3GPP)) 0181 || interfaces_and_properties.keys().contains(QLatin1String(MMQT_DBUS_INTERFACE_MODEM_MODEMCDMA)))) { 0182 Q_EMIT modemAdded(uni); 0183 } 0184 } 0185 0186 void ModemManager::ModemManagerPrivate::onInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces) 0187 { 0188 // TODO control removed bearers and sim cards 0189 0190 const QString uni = object_path.path(); 0191 0192 /* Ignore non-modems */ 0193 if (!uni.startsWith(QLatin1String(MMQT_DBUS_MODEM_PREFIX))) { 0194 return; 0195 } 0196 0197 qCDebug(MMQT) << uni << "lost interfaces:" << interfaces; 0198 0199 ModemDevice::Ptr modem = findModemDevice(uni); 0200 0201 // Remove modem when there is no interface or Modem interfaces has been removed 0202 if (!uni.isEmpty() && (interfaces.isEmpty() || (modem && modem->interfaces().isEmpty()) || interfaces.contains(QLatin1String(MMQT_DBUS_INTERFACE_MODEM)))) { 0203 Q_EMIT modemRemoved(uni); 0204 modemList.remove(uni); 0205 } 0206 } 0207 0208 ModemManager::ModemDevice::Ptr ModemManager::findModemDevice(const QString &uni) 0209 { 0210 return globalModemManager->findModemDevice(uni); 0211 } 0212 0213 ModemManager::ModemDevice::List ModemManager::modemDevices() 0214 { 0215 return globalModemManager->modemDevices(); 0216 } 0217 0218 ModemManager::Notifier *ModemManager::notifier() 0219 { 0220 return globalModemManager; 0221 } 0222 0223 void ModemManager::scanDevices() 0224 { 0225 globalModemManager->scanDevices(); 0226 } 0227 0228 #include "moc_manager.cpp" 0229 #include "moc_manager_p.cpp"