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