Changeset View
Changeset View
Standalone View
Standalone View
libs/handler.cpp
Show All 14 Lines | 1 | /* | |||
---|---|---|---|---|---|
15 | Lesser General Public License for more details. | 15 | Lesser General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU Lesser General Public | 17 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | 18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "handler.h" | 21 | #include "handler.h" | ||
22 | #include "connectioneditordialog.h" | 22 | #include "connectioneditordialog.h" | ||
23 | #include "configuration.h" | ||||
23 | #include "uiutils.h" | 24 | #include "uiutils.h" | ||
24 | #include "debug.h" | 25 | #include "debug.h" | ||
25 | 26 | | |||
26 | #include <NetworkManagerQt/Manager> | 27 | #include <NetworkManagerQt/Manager> | ||
27 | #include <NetworkManagerQt/AccessPoint> | 28 | #include <NetworkManagerQt/AccessPoint> | ||
28 | #include <NetworkManagerQt/WiredDevice> | 29 | #include <NetworkManagerQt/WiredDevice> | ||
29 | #include <NetworkManagerQt/WirelessDevice> | 30 | #include <NetworkManagerQt/WirelessDevice> | ||
30 | #include <NetworkManagerQt/Settings> | 31 | #include <NetworkManagerQt/Settings> | ||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Line(s) | 76 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | |||
78 | QStringLiteral("registered"), | 79 | QStringLiteral("registered"), | ||
79 | this, SLOT(initKdedModule())); | 80 | this, SLOT(initKdedModule())); | ||
80 | 81 | | |||
81 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | 82 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | ||
82 | QStringLiteral(AGENT_PATH), | 83 | QStringLiteral(AGENT_PATH), | ||
83 | QStringLiteral(AGENT_IFACE), | 84 | QStringLiteral(AGENT_IFACE), | ||
84 | QStringLiteral("secretsError"), | 85 | QStringLiteral("secretsError"), | ||
85 | this, SLOT(secretAgentError(QString, QString))); | 86 | this, SLOT(secretAgentError(QString, QString))); | ||
87 | | ||||
88 | m_hotspotSupported = checkHotspotSupported(); | ||||
89 | | ||||
90 | if (NetworkManager::checkVersion(1, 16, 0)) { | ||||
91 | connect(NetworkManager::notifier(), &NetworkManager::Notifier::primaryConnectionTypeChanged, [this] () { | ||||
92 | m_hotspotSupported = checkHotspotSupported(); | ||||
93 | Q_EMIT hotspotSupportedChanged(m_hotspotSupported); | ||||
94 | }); | ||||
95 | } | ||||
86 | } | 96 | } | ||
87 | 97 | | |||
88 | Handler::~Handler() | 98 | Handler::~Handler() | ||
89 | { | 99 | { | ||
90 | } | 100 | } | ||
91 | 101 | | |||
92 | void Handler::activateConnection(const QString& connection, const QString& device, const QString& specificObject) | 102 | void Handler::activateConnection(const QString& connection, const QString& device, const QString& specificObject) | ||
93 | { | 103 | { | ||
▲ Show 20 Lines • Show All 429 Lines • ▼ Show 20 Line(s) | 501 | if (wifiDevice && wifiDevice->state() != NetworkManager::WirelessDevice::Unavailable) { | |||
523 | watcher->setProperty("action", Handler::RequestScan); | 533 | watcher->setProperty("action", Handler::RequestScan); | ||
524 | watcher->setProperty("interface", wifiDevice->interfaceName()); | 534 | watcher->setProperty("interface", wifiDevice->interfaceName()); | ||
525 | connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); | 535 | connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); | ||
526 | } | 536 | } | ||
527 | } | 537 | } | ||
528 | } | 538 | } | ||
529 | } | 539 | } | ||
530 | 540 | | |||
541 | void Handler::createHotspot() | ||||
542 | { | ||||
543 | bool foundInactive = false; | ||||
544 | bool useApMode = false; | ||||
545 | NetworkManager::WirelessDevice::Ptr wifiDev; | ||||
546 | | ||||
547 | NetworkManager::ConnectionSettings::Ptr connectionSettings; | ||||
548 | connectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); | ||||
549 | | ||||
550 | NetworkManager::WirelessSetting::Ptr wifiSetting = connectionSettings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>(); | ||||
551 | wifiSetting->setMode(NetworkManager::WirelessSetting::Adhoc); | ||||
552 | wifiSetting->setSsid(Configuration::hotspotName().toUtf8()); | ||||
553 | | ||||
554 | for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) { | ||||
555 | if (device->type() == NetworkManager::Device::Wifi) { | ||||
556 | wifiDev = device.objectCast<NetworkManager::WirelessDevice>(); | ||||
557 | if (wifiDev) { | ||||
558 | if (!wifiDev->isActive()) { | ||||
559 | foundInactive = true; | ||||
560 | } else { | ||||
561 | // Prefer previous device if it was inactive | ||||
562 | if (foundInactive) { | ||||
563 | break; | ||||
564 | } | ||||
565 | } | ||||
566 | | ||||
567 | if (wifiDev->wirelessCapabilities().testFlag(NetworkManager::WirelessDevice::ApCap)) { | ||||
568 | useApMode = true; | ||||
569 | } | ||||
570 | | ||||
571 | // We prefer inactive wireless card with AP capabilities | ||||
572 | if (foundInactive && useApMode) { | ||||
573 | break; | ||||
574 | } | ||||
575 | } | ||||
576 | } | ||||
577 | } | ||||
578 | | ||||
579 | if (!wifiDev) { | ||||
580 | qCWarning(PLASMA_NM) << "Failed to create hotspot: missing wireless device"; | ||||
581 | return; | ||||
582 | } | ||||
583 | | ||||
584 | wifiSetting->setInitialized(true); | ||||
585 | wifiSetting->setMode(useApMode ? NetworkManager::WirelessSetting::Ap :NetworkManager::WirelessSetting::Adhoc); | ||||
586 | | ||||
587 | if (!Configuration::hotspotPassword().isEmpty()) { | ||||
588 | NetworkManager::WirelessSecuritySetting::Ptr wifiSecurity = connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast<NetworkManager::WirelessSecuritySetting>(); | ||||
589 | wifiSecurity->setInitialized(true); | ||||
590 | | ||||
591 | if (useApMode) { | ||||
592 | // Use WPA2 | ||||
593 | wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); | ||||
594 | wifiSecurity->setPsk(Configuration::hotspotPassword()); | ||||
595 | wifiSecurity->setPskFlags(NetworkManager::Setting::AgentOwned); | ||||
596 | } else { | ||||
597 | // Use WEP | ||||
598 | wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Wep); | ||||
599 | wifiSecurity->setWepKeyType(NetworkManager::WirelessSecuritySetting::Passphrase); | ||||
600 | wifiSecurity->setWepTxKeyindex(0); | ||||
601 | wifiSecurity->setWepKey0(Configuration::hotspotPassword()); | ||||
602 | wifiSecurity->setWepKeyFlags(NetworkManager::Setting::AgentOwned); | ||||
603 | wifiSecurity->setAuthAlg(NetworkManager::WirelessSecuritySetting::Open); | ||||
604 | } | ||||
605 | } | ||||
606 | | ||||
607 | NetworkManager::Ipv4Setting::Ptr ipv4Setting = connectionSettings->setting(NetworkManager::Setting::Ipv4).dynamicCast<NetworkManager::Ipv4Setting>(); | ||||
608 | ipv4Setting->setMethod(NetworkManager::Ipv4Setting::Shared); | ||||
609 | ipv4Setting->setInitialized(true); | ||||
610 | | ||||
611 | connectionSettings->setId(Configuration::hotspotName()); | ||||
612 | connectionSettings->setAutoconnect(false); | ||||
613 | connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); | ||||
614 | | ||||
615 | const QVariantMap options = { {QLatin1String("persist"), QLatin1String("volatile")} }; | ||||
apol: I'd prefer the initializer list syntax
`const QVariantMap options = { {QLatin1String("persist")… | |||||
616 | | ||||
617 | QDBusPendingReply<QDBusObjectPath, QDBusObjectPath, QVariantMap> reply = NetworkManager::addAndActivateConnection2(connectionSettings->toMap(), wifiDev->uni(), QString(), options); | ||||
618 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); | ||||
619 | watcher->setProperty("action", Handler::CreateHotspot); | ||||
620 | watcher->setProperty("connection", Configuration::hotspotName()); | ||||
621 | connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); | ||||
622 | connect(watcher, &QDBusPendingCallWatcher::finished, this, QOverload<QDBusPendingCallWatcher *>::of(&Handler::hotspotCreated)); | ||||
623 | } | ||||
apol: Use QOverload instead of static_cast, for readability. | |||||
624 | | ||||
625 | void Handler::stopHotspot() | ||||
626 | { | ||||
627 | const QString activeConnectionPath = Configuration::hotspotConnectionPath(); | ||||
628 | | ||||
629 | if (activeConnectionPath.isEmpty()) { | ||||
630 | return; | ||||
631 | } | ||||
632 | | ||||
633 | NetworkManager::ActiveConnection::Ptr hotspot = NetworkManager::findActiveConnection(activeConnectionPath); | ||||
634 | | ||||
635 | if (!hotspot) { | ||||
636 | return; | ||||
637 | } | ||||
638 | | ||||
639 | NetworkManager::deactivateConnection(activeConnectionPath); | ||||
640 | Configuration::setHotspotConnectionPath(QString()); | ||||
641 | | ||||
642 | Q_EMIT hotspotDisabled(); | ||||
643 | } | ||||
644 | | ||||
531 | bool Handler::checkRequestScanRateLimit(const NetworkManager::WirelessDevice::Ptr &wifiDevice) | 645 | bool Handler::checkRequestScanRateLimit(const NetworkManager::WirelessDevice::Ptr &wifiDevice) | ||
532 | { | 646 | { | ||
533 | QDateTime now = QDateTime::currentDateTime(); | 647 | QDateTime now = QDateTime::currentDateTime(); | ||
534 | QDateTime lastScan = wifiDevice->lastScan(); | 648 | QDateTime lastScan = wifiDevice->lastScan(); | ||
535 | QDateTime lastRequestScan = wifiDevice->lastRequestScan(); | 649 | QDateTime lastRequestScan = wifiDevice->lastRequestScan(); | ||
536 | 650 | | |||
537 | // if the last scan finished within the last 10 seconds | 651 | // if the last scan finished within the last 10 seconds | ||
538 | bool ret = lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; | 652 | bool ret = lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; | ||
539 | // or if the last Request was sent within the last 10 seconds | 653 | // or if the last Request was sent within the last 10 seconds | ||
540 | ret |= lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; | 654 | ret |= lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; | ||
541 | // skip the request scan | 655 | // skip the request scan | ||
542 | if (ret) { | 656 | if (ret) { | ||
543 | qCDebug(PLASMA_NM) << "Last scan finished " << lastScan.msecsTo(now) << "ms ago and last request scan was sent " | 657 | qCDebug(PLASMA_NM) << "Last scan finished " << lastScan.msecsTo(now) << "ms ago and last request scan was sent " | ||
544 | << lastRequestScan.msecsTo(now) << "ms ago, Skipping scanning interface:" << wifiDevice->interfaceName(); | 658 | << lastRequestScan.msecsTo(now) << "ms ago, Skipping scanning interface:" << wifiDevice->interfaceName(); | ||
545 | return false; | 659 | return false; | ||
546 | } | 660 | } | ||
547 | return true; | 661 | return true; | ||
548 | } | 662 | } | ||
549 | 663 | | |||
664 | bool Handler::checkHotspotSupported() | ||||
665 | { | ||||
666 | if (NetworkManager::checkVersion(1, 16, 0)) { | ||||
667 | bool unusedWifiFound = false; | ||||
668 | bool wifiFound = false; | ||||
669 | | ||||
670 | for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) { | ||||
671 | if (device->type() == NetworkManager::Device::Wifi) { | ||||
672 | wifiFound = true; | ||||
673 | | ||||
674 | NetworkManager::WirelessDevice::Ptr wifiDev = device.objectCast<NetworkManager::WirelessDevice>(); | ||||
675 | if (wifiDev && !wifiDev->isActive()) { | ||||
676 | unusedWifiFound = true; | ||||
677 | } | ||||
678 | } | ||||
679 | } | ||||
680 | | ||||
681 | | ||||
682 | if (!wifiFound) { | ||||
683 | return false; | ||||
684 | } | ||||
685 | | ||||
686 | if (unusedWifiFound) { | ||||
687 | return true; | ||||
688 | } | ||||
689 | | ||||
690 | // Check if the primary connection which is used for internet connectivity is not using WiFi | ||||
691 | if (NetworkManager::primaryConnectionType() != NetworkManager::ConnectionSettings::Wireless) { | ||||
692 | return true; | ||||
693 | } | ||||
694 | } | ||||
695 | | ||||
696 | return false; | ||||
697 | } | ||||
698 | | ||||
550 | void Handler::scheduleRequestScan(const QString &interface, int timeout) | 699 | void Handler::scheduleRequestScan(const QString &interface, int timeout) | ||
551 | { | 700 | { | ||
552 | QTimer *timer; | 701 | QTimer *timer; | ||
553 | if (!m_wirelessScanRetryTimer.contains(interface)) { | 702 | if (!m_wirelessScanRetryTimer.contains(interface)) { | ||
554 | // create a timer for the interface | 703 | // create a timer for the interface | ||
555 | timer = new QTimer(); | 704 | timer = new QTimer(); | ||
556 | timer->setSingleShot(true); | 705 | timer->setSingleShot(true); | ||
557 | m_wirelessScanRetryTimer.insert(interface, timer); | 706 | m_wirelessScanRetryTimer.insert(interface, timer); | ||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Line(s) | 774 | case Handler::UpdateConnection: | |||
628 | break; | 777 | break; | ||
629 | case Handler::RequestScan: | 778 | case Handler::RequestScan: | ||
630 | { | 779 | { | ||
631 | const QString interface = watcher->property("interface").toString(); | 780 | const QString interface = watcher->property("interface").toString(); | ||
632 | qCWarning(PLASMA_NM) << "Wireless scan on" << interface << "failed:" << error; | 781 | qCWarning(PLASMA_NM) << "Wireless scan on" << interface << "failed:" << error; | ||
633 | scanRequestFailed(interface); | 782 | scanRequestFailed(interface); | ||
634 | break; | 783 | break; | ||
635 | } | 784 | } | ||
785 | case Handler::CreateHotspot: | ||||
786 | notification = new KNotification("FailedToCreateHotspot", KNotification::CloseOnTimeout, this); | ||||
787 | notification->setTitle(i18n("Failed to create hotspot %1", watcher->property("connection").toString())); | ||||
788 | break; | ||||
636 | default: | 789 | default: | ||
637 | break; | 790 | break; | ||
638 | } | 791 | } | ||
639 | 792 | | |||
640 | if (notification) { | 793 | if (notification) { | ||
641 | notification->setComponentName("networkmanagement"); | 794 | notification->setComponentName("networkmanagement"); | ||
642 | notification->setText(error); | 795 | notification->setText(error); | ||
643 | notification->setIconName(QStringLiteral("dialog-warning")); | 796 | notification->setIconName(QStringLiteral("dialog-warning")); | ||
Show All 29 Lines | 823 | if (notification) { | |||
673 | notification->setIconName(QStringLiteral("dialog-information")); | 826 | notification->setIconName(QStringLiteral("dialog-information")); | ||
674 | notification->sendEvent(); | 827 | notification->sendEvent(); | ||
675 | } | 828 | } | ||
676 | } | 829 | } | ||
677 | 830 | | |||
678 | watcher->deleteLater(); | 831 | watcher->deleteLater(); | ||
679 | } | 832 | } | ||
680 | 833 | | |||
834 | void Handler::hotspotCreated(QDBusPendingCallWatcher *watcher) | ||||
835 | { | ||||
836 | QDBusPendingReply<QDBusObjectPath, QDBusObjectPath, QVariantMap> reply = *watcher; | ||||
837 | | ||||
838 | if (!reply.isError() && reply.isValid()) { | ||||
839 | const QString activeConnectionPath = reply.argumentAt(1).value<QDBusObjectPath>().path(); | ||||
840 | | ||||
841 | if (activeConnectionPath.isEmpty()) { | ||||
842 | return; | ||||
843 | } | ||||
844 | | ||||
845 | Configuration::setHotspotConnectionPath(activeConnectionPath); | ||||
846 | | ||||
847 | NetworkManager::ActiveConnection::Ptr hotspot = NetworkManager::findActiveConnection(activeConnectionPath); | ||||
848 | | ||||
849 | if (!hotspot) { | ||||
850 | return; | ||||
851 | } | ||||
852 | | ||||
853 | connect(hotspot.data(), &NetworkManager::ActiveConnection::stateChanged, [=] (NetworkManager::ActiveConnection::State state) { | ||||
854 | if (state > NetworkManager::ActiveConnection::Activated) { | ||||
855 | Configuration::setHotspotConnectionPath(QString()); | ||||
856 | Q_EMIT hotspotDisabled(); | ||||
857 | } | ||||
858 | }); | ||||
859 | | ||||
860 | Q_EMIT hotspotCreated(); | ||||
861 | } | ||||
862 | } | ||||
863 | | ||||
681 | #if WITH_MODEMMANAGER_SUPPORT | 864 | #if WITH_MODEMMANAGER_SUPPORT | ||
682 | void Handler::unlockRequiredChanged(MMModemLock modemLock) | 865 | void Handler::unlockRequiredChanged(MMModemLock modemLock) | ||
683 | { | 866 | { | ||
684 | if (modemLock == MM_MODEM_LOCK_NONE) { | 867 | if (modemLock == MM_MODEM_LOCK_NONE) { | ||
685 | activateConnection(m_tmpConnectionPath, m_tmpDevicePath, m_tmpSpecificPath); | 868 | activateConnection(m_tmpConnectionPath, m_tmpDevicePath, m_tmpSpecificPath); | ||
686 | } | 869 | } | ||
687 | } | 870 | } | ||
688 | #endif | 871 | #endif | ||
689 | 872 | |
I'd prefer the initializer list syntax
const QVariantMap options = { {QLatin1String("persist"), QLatin1String("volatile")} };