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