File indexing completed on 2024-04-14 15:39:56
0001 /* 0002 SPDX-FileCopyrightText: 2009 Will Stephenson <wstephenson@kde.org> 0003 SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com> 0004 SPDX-FileCopyrightText: 2014 Jan Grulich <jgrulich@redhat.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "modemmonitor.h" 0010 #include "plasma_nm_kded.h" 0011 0012 #include <QDBusPendingReply> 0013 0014 #include <KConfigGroup> 0015 #include <KLocalizedString> 0016 #include <KMessageBox> 0017 #include <KSharedConfig> 0018 0019 #include <NetworkManagerQt/Connection> 0020 #include <NetworkManagerQt/Device> 0021 #include <NetworkManagerQt/GsmSetting> 0022 #include <NetworkManagerQt/Manager> 0023 0024 #include <ModemManager/ModemManager.h> 0025 #include <ModemManagerQt/Manager> 0026 #include <ModemManagerQt/Sim> 0027 0028 #include "pindialog.h" 0029 0030 class ModemMonitorPrivate 0031 { 0032 public: 0033 QPointer<PinDialog> dialog; 0034 }; 0035 0036 ModemMonitor::ModemMonitor(QObject *parent) 0037 : QObject(parent) 0038 , d_ptr(new ModemMonitorPrivate) 0039 { 0040 Q_D(ModemMonitor); 0041 d->dialog.clear(); 0042 0043 KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String("plasma-nm")); 0044 KConfigGroup grp(config, QLatin1String("General")); 0045 0046 if (grp.isValid()) { 0047 if (grp.readEntry(QLatin1String("UnlockModemOnDetection"), true)) { 0048 connect(ModemManager::notifier(), &ModemManager::Notifier::modemAdded, this, &ModemMonitor::unlockModem); 0049 for (const ModemManager::ModemDevice::Ptr &iface : ModemManager::modemDevices()) { 0050 unlockModem(iface->uni()); 0051 } 0052 } 0053 } 0054 } 0055 0056 ModemMonitor::~ModemMonitor() 0057 { 0058 delete d_ptr; 0059 } 0060 0061 void ModemMonitor::unlockModem(const QString &modemUni) 0062 { 0063 Q_D(ModemMonitor); 0064 0065 ModemManager::Modem::Ptr modem; 0066 ModemManager::ModemDevice::Ptr modemDevice = ModemManager::findModemDevice(modemUni); 0067 if (modemDevice) { 0068 modem = modemDevice->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>(); 0069 } else { 0070 return; 0071 } 0072 0073 connect(modem.data(), &ModemManager::Modem::unlockRequiredChanged, this, &ModemMonitor::requestPin, Qt::UniqueConnection); 0074 0075 if (d->dialog || (modem && modem->unlockRequired() == MM_MODEM_LOCK_NONE) || (modem && modem->unlockRequired() == MM_MODEM_LOCK_UNKNOWN)) { 0076 return; 0077 } 0078 0079 if (modem) { 0080 // Using queued invocation to prevent kded stalling here until user enters the pin. 0081 QMetaObject::invokeMethod(modem.data(), "unlockRequiredChanged", Qt::QueuedConnection, Q_ARG(MMModemLock, modem->unlockRequired())); 0082 } 0083 } 0084 0085 void ModemMonitor::requestPin(MMModemLock lock) 0086 { 0087 Q_D(ModemMonitor); 0088 qCDebug(PLASMA_NM_KDED_LOG) << "unlockRequired == " << lock; 0089 // Handle just SIM-PIN and SIM-PUK, because some other types may cause problems and they are not also handled by nm-applet 0090 if (lock == MM_MODEM_LOCK_NONE || lock == MM_MODEM_LOCK_UNKNOWN || (lock != MM_MODEM_LOCK_SIM_PIN && lock != MM_MODEM_LOCK_SIM_PUK)) { 0091 return; 0092 } 0093 0094 auto modem = qobject_cast<ModemManager::Modem *>(sender()); 0095 if (!modem) { 0096 return; 0097 } 0098 0099 if (d->dialog) { 0100 qCDebug(PLASMA_NM_KDED_LOG) << "PinDialog already running"; 0101 return; 0102 } 0103 0104 #define MM_DIALOG(lockType, dialogType) \ 0105 if (lock == lockType) { \ 0106 d->dialog = QPointer<PinDialog>(new PinDialog(modem, PinDialog::dialogType)); \ 0107 } 0108 0109 // clang-format off 0110 /**/ MM_DIALOG(MM_MODEM_LOCK_SIM_PIN, SimPin) 0111 else MM_DIALOG(MM_MODEM_LOCK_SIM_PIN2, SimPin2) 0112 else MM_DIALOG(MM_MODEM_LOCK_SIM_PUK, SimPuk) 0113 else MM_DIALOG(MM_MODEM_LOCK_SIM_PUK2, SimPuk2) 0114 else MM_DIALOG(MM_MODEM_LOCK_PH_SP_PIN, ModemServiceProviderPin) 0115 else MM_DIALOG(MM_MODEM_LOCK_PH_SP_PUK, ModemServiceProviderPuk) 0116 else MM_DIALOG(MM_MODEM_LOCK_PH_NET_PIN, ModemNetworkPin) 0117 else MM_DIALOG(MM_MODEM_LOCK_PH_NET_PUK, ModemNetworkPuk) 0118 else MM_DIALOG(MM_MODEM_LOCK_PH_SIM_PIN, ModemPin) 0119 else MM_DIALOG(MM_MODEM_LOCK_PH_CORP_PIN, ModemCorporatePin) 0120 else MM_DIALOG(MM_MODEM_LOCK_PH_CORP_PUK, ModemCorporatePuk) 0121 else MM_DIALOG(MM_MODEM_LOCK_PH_FSIM_PIN, ModemPhFsimPin) 0122 else MM_DIALOG(MM_MODEM_LOCK_PH_FSIM_PUK, ModemPhFsimPuk) 0123 else MM_DIALOG(MM_MODEM_LOCK_PH_NETSUB_PIN, ModemNetworkSubsetPin) 0124 else MM_DIALOG(MM_MODEM_LOCK_PH_NETSUB_PUK, ModemNetworkSubsetPuk); 0125 // clang-format on 0126 0127 if (d->dialog.data()->exec() != QDialog::Accepted) { 0128 goto OUT; 0129 } 0130 0131 qCDebug(PLASMA_NM_KDED_LOG) << "Sending unlock code"; 0132 0133 { 0134 ModemManager::Sim::Ptr sim; 0135 ModemManager::ModemDevice::Ptr modemDevice = ModemManager::findModemDevice(modem->uni()); 0136 if (modemDevice && modemDevice->sim()) { 0137 sim = modemDevice->sim(); 0138 } 0139 0140 if (!sim) { 0141 return; 0142 } 0143 0144 QDBusPendingCallWatcher *watcher = nullptr; 0145 0146 PinDialog::Type type = d->dialog.data()->type(); 0147 0148 if (type == PinDialog::SimPin || type == PinDialog::SimPin2 // 0149 || type == PinDialog::ModemServiceProviderPin || type == PinDialog::ModemNetworkPin // 0150 || type == PinDialog::ModemPin || type == PinDialog::ModemCorporatePin // 0151 || type == PinDialog::ModemPhFsimPin || type == PinDialog::ModemNetworkSubsetPin) { 0152 QDBusPendingCall reply = sim->sendPin(d->dialog.data()->pin()); 0153 watcher = new QDBusPendingCallWatcher(reply, sim.data()); 0154 } else if (type == PinDialog::SimPuk // 0155 || type == PinDialog::SimPuk2 || type == PinDialog::ModemServiceProviderPuk // 0156 || type == PinDialog::ModemNetworkPuk || type == PinDialog::ModemCorporatePuk // 0157 || type == PinDialog::ModemPhFsimPuk || type == PinDialog::ModemNetworkSubsetPuk) { 0158 QDBusPendingCall reply = sim->sendPuk(d->dialog.data()->puk(), d->dialog.data()->pin()); 0159 watcher = new QDBusPendingCallWatcher(reply, sim.data()); 0160 } 0161 0162 connect(watcher, &QDBusPendingCallWatcher::finished, this, &ModemMonitor::onSendPinArrived); 0163 } 0164 0165 OUT: 0166 if (d->dialog) { 0167 d->dialog.data()->deleteLater(); 0168 } 0169 d->dialog.clear(); 0170 } 0171 0172 void ModemMonitor::onSendPinArrived(QDBusPendingCallWatcher *watcher) 0173 { 0174 QDBusPendingReply<> reply = *watcher; 0175 0176 if (reply.isValid()) { 0177 // Automatically enabling this for cell phones with expensive data plans is not a good idea. 0178 // NetworkManager::setWwanEnabled(true); 0179 } else { 0180 KMessageBox::error(nullptr, 0181 i18nc("Text in GSM PIN/PUK unlock error dialog", "Error unlocking modem: %1", reply.error().message()), 0182 i18nc("Title for GSM PIN/PUK unlock error dialog", "PIN/PUK unlock error")); 0183 } 0184 0185 watcher->deleteLater(); 0186 }