wificonnectionwidget.cpp 7.22 KB
Newer Older
Jan Grulich's avatar
Jan Grulich committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
    Copyright (c) 2013 Lukas Tinkl <ltinkl@redhat.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

21
#include "debug.h"
Jan Grulich's avatar
Jan Grulich committed
22
23
#include "wificonnectionwidget.h"
#include "ui_wificonnectionwidget.h"
24

25
#include <NetworkManagerQt/Utils>
26
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
27
#include <QRandomGenerator>
28

29
#include "uiutils.h"
Jan Grulich's avatar
Jan Grulich committed
30

31
WifiConnectionWidget::WifiConnectionWidget(const NetworkManager::Setting::Ptr &setting, QWidget* parent, Qt::WindowFlags f):
Jan Grulich's avatar
Jan Grulich committed
32
33
34
35
36
    SettingWidget(setting, parent, f),
    m_ui(new Ui::WifiConnectionWidget)
{
    m_ui->setupUi(this);

37
    connect(m_ui->btnRandomMacAddr, &QPushButton::clicked, this, &WifiConnectionWidget::generateRandomClonedMac);
38
39
40
    connect(m_ui->SSIDCombo, &SsidComboBox::ssidChanged, this, QOverload<>::of(&WifiConnectionWidget::ssidChanged));
    connect(m_ui->modeComboBox, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &WifiConnectionWidget::modeChanged);
    connect(m_ui->band, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &WifiConnectionWidget::bandChanged);
41

42
43
44
45
    // Connect for setting check
    watchChangedSetting();

    // Connect for validity check
46
47
    connect(m_ui->macAddress, &HwAddrComboBox::hwAddressChanged, this, &WifiConnectionWidget::slotWidgetChanged);
    connect(m_ui->BSSIDCombo, &BssidComboBox::bssidChanged, this, &WifiConnectionWidget::slotWidgetChanged);
48

49
50
    KAcceleratorManager::manage(this);

51
    if (setting) {
Jan Grulich's avatar
Jan Grulich committed
52
        loadConfig(setting);
53
    }
Jan Grulich's avatar
Jan Grulich committed
54
55
56
57
}

WifiConnectionWidget::~WifiConnectionWidget()
{
Jan Grulich's avatar
Jan Grulich committed
58
    delete m_ui;
Jan Grulich's avatar
Jan Grulich committed
59
60
}

61
void WifiConnectionWidget::loadConfig(const NetworkManager::Setting::Ptr &setting)
Jan Grulich's avatar
Jan Grulich committed
62
{
63
    NetworkManager::WirelessSetting::Ptr wifiSetting = setting.staticCast<NetworkManager::WirelessSetting>();
Jan Grulich's avatar
Jan Grulich committed
64

Lukáš Tinkl's avatar
Lukáš Tinkl committed
65
    m_ui->SSIDCombo->init(QString::fromUtf8(wifiSetting->ssid()));
Jan Grulich's avatar
Jan Grulich committed
66

67
    if (wifiSetting->mode() != NetworkManager::WirelessSetting::Infrastructure) {
Jan Grulich's avatar
Jan Grulich committed
68
69
        m_ui->modeComboBox->setCurrentIndex(wifiSetting->mode());
    }
70
    modeChanged(wifiSetting->mode());
Jan Grulich's avatar
Jan Grulich committed
71

72
    m_ui->BSSIDCombo->init(NetworkManager::macAddressAsString(wifiSetting->bssid()), QString::fromUtf8(wifiSetting->ssid()));
Jan Grulich's avatar
Jan Grulich committed
73

74
75
76
77
78
    m_ui->band->setCurrentIndex(wifiSetting->band());
    if (wifiSetting->band() != NetworkManager::WirelessSetting::Automatic) {
        m_ui->channel->setCurrentIndex(m_ui->channel->findData(wifiSetting->channel()));
    }

Jan Grulich's avatar
Jan Grulich committed
79
    m_ui->macAddress->init(NetworkManager::Device::Wifi, NetworkManager::macAddressAsString(wifiSetting->macAddress()));
Jan Grulich's avatar
Jan Grulich committed
80
81

    if (!wifiSetting->clonedMacAddress().isEmpty()) {
Jan Grulich's avatar
Jan Grulich committed
82
        m_ui->clonedMacAddress->setText(NetworkManager::macAddressAsString(wifiSetting->clonedMacAddress()));
Jan Grulich's avatar
Jan Grulich committed
83
84
85
86
87
    }

    if (wifiSetting->mtu()) {
        m_ui->mtu->setValue(wifiSetting->mtu());
    }
88
89
90
91

    if (wifiSetting->hidden()) {
        m_ui->hiddenNetwork->setChecked(true);
    }
Jan Grulich's avatar
Jan Grulich committed
92
93
}

94
QVariantMap WifiConnectionWidget::setting() const
Jan Grulich's avatar
Jan Grulich committed
95
{
96
    NetworkManager::WirelessSetting wifiSetting;
Jan Grulich's avatar
Jan Grulich committed
97

98
    wifiSetting.setSsid(m_ui->SSIDCombo->ssid().toUtf8());
Jan Grulich's avatar
Jan Grulich committed
99

100
    wifiSetting.setMode(static_cast<NetworkManager::WirelessSetting::NetworkMode>(m_ui->modeComboBox->currentIndex()));
Jan Grulich's avatar
Jan Grulich committed
101

Jan Grulich's avatar
Jan Grulich committed
102
    wifiSetting.setBssid(NetworkManager::macAddressFromString(m_ui->BSSIDCombo->bssid()));
Jan Grulich's avatar
Jan Grulich committed
103

104
105
106
107
108
    if (wifiSetting.mode() != NetworkManager::WirelessSetting::Infrastructure && m_ui->band->currentIndex() != 0) {
        wifiSetting.setBand((NetworkManager::WirelessSetting::FrequencyBand)m_ui->band->currentIndex());
        wifiSetting.setChannel(m_ui->channel->itemData(m_ui->channel->currentIndex()).toUInt());
    }

Jan Grulich's avatar
Jan Grulich committed
109
    wifiSetting.setMacAddress(NetworkManager::macAddressFromString(m_ui->macAddress->hwAddress()));
Jan Grulich's avatar
Jan Grulich committed
110
111

    if (!m_ui->clonedMacAddress->text().isEmpty() && m_ui->clonedMacAddress->text() != ":::::") {
Jan Grulich's avatar
Jan Grulich committed
112
        wifiSetting.setClonedMacAddress(NetworkManager::macAddressFromString(m_ui->clonedMacAddress->text()));
Jan Grulich's avatar
Jan Grulich committed
113
114
115
116
117
118
    }

    if (m_ui->mtu->value()) {
        wifiSetting.setMtu(m_ui->mtu->value());
    }

119
120
    wifiSetting.setHidden(m_ui->hiddenNetwork->isChecked());

Jan Grulich's avatar
Jan Grulich committed
121
122
    return wifiSetting.toMap();
}
123
124
125
126

void WifiConnectionWidget::generateRandomClonedMac()
{
    QByteArray mac;
Laurent Montel's avatar
Laurent Montel committed
127
    auto *generator = QRandomGenerator::global();
128
129
    mac.resize(6);
    for (int i = 0; i < 6; i++) {
Laurent Montel's avatar
Laurent Montel committed
130
        const int random = generator->bounded(255);
131
132
        mac[i] = random;
    }
133
134
135
136
137

    // Disable the multicast bit and enable the locally administered bit.
    mac[0] = mac[0] & ~0x1;
    mac[0] = mac[0] |  0x2;

Jan Grulich's avatar
Jan Grulich committed
138
    m_ui->clonedMacAddress->setText(NetworkManager::macAddressAsString(mac));
139
}
140
141
142
143

void WifiConnectionWidget::ssidChanged()
{
    m_ui->BSSIDCombo->init(m_ui->BSSIDCombo->bssid(), m_ui->SSIDCombo->ssid());
144
    slotWidgetChanged();
145
146
147

    // Emit that SSID has changed so we can pre-configure wireless security
    Q_EMIT ssidChanged(m_ui->SSIDCombo->ssid());
148
149
}

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
void WifiConnectionWidget::modeChanged(int mode)
{
    if (mode == NetworkManager::WirelessSetting::Infrastructure) {
        m_ui->BSSIDLabel->setVisible(true);
        m_ui->BSSIDCombo->setVisible(true);
        m_ui->bandLabel->setVisible(false);
        m_ui->band->setVisible(false);
        m_ui->channelLabel->setVisible(false);
        m_ui->channel->setVisible(false);
    } else {
        m_ui->BSSIDLabel->setVisible(false);
        m_ui->BSSIDCombo->setVisible(false);
        m_ui->bandLabel->setVisible(true);
        m_ui->band->setVisible(true);
        m_ui->channelLabel->setVisible(true);
        m_ui->channel->setVisible(true);
    }
}

void WifiConnectionWidget::bandChanged(int band)
{
    m_ui->channel->clear();

    if (band == NetworkManager::WirelessSetting::Automatic) {
        m_ui->channel->setEnabled(false);
    } else {
        fillChannels((NetworkManager::WirelessSetting::FrequencyBand)band);
        m_ui->channel->setEnabled(true);
    }
}

void WifiConnectionWidget::fillChannels(NetworkManager::WirelessSetting::FrequencyBand band)
{
    QList<QPair<int, int> > channels;

    if (band == NetworkManager::WirelessSetting::A) {
Jan Grulich's avatar
Jan Grulich committed
186
        channels = NetworkManager::getAFreqs();
187
    } else if (band == NetworkManager::WirelessSetting::Bg) {
Jan Grulich's avatar
Jan Grulich committed
188
        channels = NetworkManager::getBFreqs();
189
    } else {
190
        qCWarning(PLASMA_NM) << Q_FUNC_INFO << "Unhandled band number" << band;
191
192
193
194
195
196
197
198
199
200
        return;
    }

    QListIterator<QPair<int,int> > i(channels);
    while (i.hasNext()) {
        QPair<int,int> channel = i.next();
        m_ui->channel->addItem(i18n("%1 (%2 MHz)", channel.first, channel.second), channel.first);
    }
}

201
bool WifiConnectionWidget::isValid() const
202
{
203
    return !m_ui->SSIDCombo->currentText().isEmpty() && m_ui->macAddress->isValid() && m_ui->BSSIDCombo->isValid();
204
}