File indexing completed on 2024-07-21 07:58:05

0001 /*
0002     SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "wificonnectionwidget.h"
0008 #include "plasma_nm_editor.h"
0009 #include "ui_wificonnectionwidget.h"
0010 
0011 #include <KLocalizedString>
0012 #include <NetworkManagerQt/Utils>
0013 #include <QRandomGenerator>
0014 
0015 WifiConnectionWidget::WifiConnectionWidget(const NetworkManager::Setting::Ptr &setting, QWidget *parent, Qt::WindowFlags f)
0016     : SettingWidget(setting, parent, f)
0017     , m_ui(new Ui::WifiConnectionWidget)
0018 {
0019     m_ui->setupUi(this);
0020 
0021     connect(m_ui->btnRandomMacAddr, &QPushButton::clicked, this, &WifiConnectionWidget::generateRandomClonedMac);
0022     connect(m_ui->SSIDCombo, &SsidComboBox::ssidChanged, this, QOverload<>::of(&WifiConnectionWidget::ssidChanged));
0023     connect(m_ui->modeComboBox, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &WifiConnectionWidget::modeChanged);
0024     connect(m_ui->band, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &WifiConnectionWidget::bandChanged);
0025 
0026     // Connect for setting check
0027     watchChangedSetting();
0028 
0029     // Connect for validity check
0030     connect(m_ui->macAddress, &HwAddrComboBox::hwAddressChanged, this, &WifiConnectionWidget::slotWidgetChanged);
0031     connect(m_ui->BSSIDCombo, &BssidComboBox::bssidChanged, this, &WifiConnectionWidget::slotWidgetChanged);
0032 
0033     KAcceleratorManager::manage(this);
0034 
0035     if (setting) {
0036         loadConfig(setting);
0037     }
0038 }
0039 
0040 WifiConnectionWidget::~WifiConnectionWidget()
0041 {
0042     delete m_ui;
0043 }
0044 
0045 void WifiConnectionWidget::loadConfig(const NetworkManager::Setting::Ptr &setting)
0046 {
0047     NetworkManager::WirelessSetting::Ptr wifiSetting = setting.staticCast<NetworkManager::WirelessSetting>();
0048 
0049     m_ui->SSIDCombo->init(QString::fromUtf8(wifiSetting->ssid()));
0050 
0051     if (wifiSetting->mode() != NetworkManager::WirelessSetting::Infrastructure) {
0052         m_ui->modeComboBox->setCurrentIndex(wifiSetting->mode());
0053     }
0054     modeChanged(wifiSetting->mode());
0055 
0056     m_ui->BSSIDCombo->init(NetworkManager::macAddressAsString(wifiSetting->bssid()), QString::fromUtf8(wifiSetting->ssid()));
0057 
0058     m_ui->band->setCurrentIndex(wifiSetting->band());
0059     if (wifiSetting->band() != NetworkManager::WirelessSetting::Automatic) {
0060         m_ui->channel->setCurrentIndex(m_ui->channel->findData(wifiSetting->channel()));
0061     }
0062 
0063     m_ui->macAddress->init(NetworkManager::Device::Wifi, NetworkManager::macAddressAsString(wifiSetting->macAddress()));
0064 
0065     if (!wifiSetting->clonedMacAddress().isEmpty()) {
0066         m_ui->clonedMacAddress->setText(NetworkManager::macAddressAsString(wifiSetting->clonedMacAddress()));
0067     }
0068 
0069     if (wifiSetting->mtu()) {
0070         m_ui->mtu->setValue(wifiSetting->mtu());
0071     }
0072 
0073     if (wifiSetting->hidden()) {
0074         m_ui->hiddenNetwork->setChecked(true);
0075     }
0076 }
0077 
0078 QVariantMap WifiConnectionWidget::setting() const
0079 {
0080     NetworkManager::WirelessSetting wifiSetting;
0081 
0082     wifiSetting.setSsid(m_ui->SSIDCombo->ssid().toUtf8());
0083 
0084     wifiSetting.setMode(static_cast<NetworkManager::WirelessSetting::NetworkMode>(m_ui->modeComboBox->currentIndex()));
0085 
0086     wifiSetting.setBssid(NetworkManager::macAddressFromString(m_ui->BSSIDCombo->bssid()));
0087 
0088     if (wifiSetting.mode() != NetworkManager::WirelessSetting::Infrastructure && m_ui->band->currentIndex() != 0) {
0089         wifiSetting.setBand((NetworkManager::WirelessSetting::FrequencyBand)m_ui->band->currentIndex());
0090         wifiSetting.setChannel(m_ui->channel->itemData(m_ui->channel->currentIndex()).toUInt());
0091     }
0092 
0093     wifiSetting.setMacAddress(NetworkManager::macAddressFromString(m_ui->macAddress->hwAddress()));
0094 
0095     if (!m_ui->clonedMacAddress->text().isEmpty() && m_ui->clonedMacAddress->text() != ":::::") {
0096         wifiSetting.setClonedMacAddress(NetworkManager::macAddressFromString(m_ui->clonedMacAddress->text()));
0097     }
0098 
0099     if (m_ui->mtu->value()) {
0100         wifiSetting.setMtu(m_ui->mtu->value());
0101     }
0102 
0103     wifiSetting.setHidden(m_ui->hiddenNetwork->isChecked());
0104 
0105     return wifiSetting.toMap();
0106 }
0107 
0108 void WifiConnectionWidget::generateRandomClonedMac()
0109 {
0110     QByteArray mac;
0111     auto generator = QRandomGenerator::global();
0112     mac.resize(6);
0113     for (int i = 0; i < 6; i++) {
0114         const int random = generator->bounded(255);
0115         mac[i] = random;
0116     }
0117 
0118     // Disable the multicast bit and enable the locally administered bit.
0119     mac[0] = mac[0] & ~0x1;
0120     mac[0] = mac[0] | 0x2;
0121 
0122     m_ui->clonedMacAddress->setText(NetworkManager::macAddressAsString(mac));
0123 }
0124 
0125 void WifiConnectionWidget::ssidChanged()
0126 {
0127     m_ui->BSSIDCombo->init(m_ui->BSSIDCombo->bssid(), m_ui->SSIDCombo->ssid());
0128     slotWidgetChanged();
0129 
0130     // Emit that SSID has changed so we can pre-configure wireless security
0131     Q_EMIT ssidChanged(m_ui->SSIDCombo->ssid());
0132 }
0133 
0134 void WifiConnectionWidget::modeChanged(int mode)
0135 {
0136     if (mode == NetworkManager::WirelessSetting::Infrastructure) {
0137         m_ui->BSSIDLabel->setVisible(true);
0138         m_ui->BSSIDCombo->setVisible(true);
0139         m_ui->bandLabel->setVisible(false);
0140         m_ui->band->setVisible(false);
0141         m_ui->channelLabel->setVisible(false);
0142         m_ui->channel->setVisible(false);
0143     } else {
0144         m_ui->BSSIDLabel->setVisible(false);
0145         m_ui->BSSIDCombo->setVisible(false);
0146         m_ui->bandLabel->setVisible(true);
0147         m_ui->band->setVisible(true);
0148         m_ui->channelLabel->setVisible(true);
0149         m_ui->channel->setVisible(true);
0150     }
0151 }
0152 
0153 void WifiConnectionWidget::bandChanged(int band)
0154 {
0155     m_ui->channel->clear();
0156 
0157     if (band == NetworkManager::WirelessSetting::Automatic) {
0158         m_ui->channel->setEnabled(false);
0159     } else {
0160         fillChannels((NetworkManager::WirelessSetting::FrequencyBand)band);
0161         m_ui->channel->setEnabled(true);
0162     }
0163 }
0164 
0165 void WifiConnectionWidget::fillChannels(NetworkManager::WirelessSetting::FrequencyBand band)
0166 {
0167     QList<QPair<int, int>> channels;
0168 
0169     if (band == NetworkManager::WirelessSetting::A) {
0170         channels = NetworkManager::getAFreqs();
0171     } else if (band == NetworkManager::WirelessSetting::Bg) {
0172         channels = NetworkManager::getBFreqs();
0173     } else {
0174         qCWarning(PLASMA_NM_EDITOR_LOG) << Q_FUNC_INFO << "Unhandled band number" << band;
0175         return;
0176     }
0177 
0178     QListIterator<QPair<int, int>> i(channels);
0179     while (i.hasNext()) {
0180         QPair<int, int> channel = i.next();
0181         m_ui->channel->addItem(i18n("%1 (%2 MHz)", channel.first, channel.second), channel.first);
0182     }
0183 }
0184 
0185 bool WifiConnectionWidget::isValid() const
0186 {
0187     return !m_ui->SSIDCombo->currentText().isEmpty() && m_ui->macAddress->isValid() && m_ui->BSSIDCombo->isValid();
0188 }
0189 
0190 #include "moc_wificonnectionwidget.cpp"