You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
12 KiB
C++
323 lines
12 KiB
C++
#include "network.h"
|
|
#include "uiutils.h"
|
|
#include <QDebug>
|
|
|
|
#include <sys/types.h>
|
|
#include <pwd.h>
|
|
|
|
Network::Network(QObject *parent)
|
|
: QObject(parent)
|
|
, m_wirelessNetwork(nullptr)
|
|
{
|
|
::passwd *pw = ::getpwuid(::getuid());
|
|
m_userName = QString::fromLocal8Bit(pw->pw_name);
|
|
|
|
connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &Network::enabledChanged);
|
|
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &Network::onWirelessEnabledChanged);
|
|
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged, this, &Network::wirelessHardwareEnabledChanged);
|
|
connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &Network::statusChanged);
|
|
connect(NetworkManager::notifier(), &NetworkManager::Notifier::activatingConnectionChanged, this, &Network::activatingConnectionChanged);
|
|
|
|
for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) {
|
|
if (device->type() == NetworkManager::Device::Wifi) {
|
|
NetworkManager::WirelessDevice::Ptr wifiDevice = device.staticCast<NetworkManager::WirelessDevice>();
|
|
if (wifiDevice) {
|
|
connect(wifiDevice.data(), &NetworkManager::WirelessDevice::availableConnectionAppeared, this, &Network::onWirelessNetworkAppeared);
|
|
connect(wifiDevice.data(), &NetworkManager::WirelessDevice::networkAppeared, this, &Network::onWirelessNetworkAppeared);
|
|
}
|
|
}
|
|
}
|
|
|
|
statusChanged(NetworkManager::status());
|
|
changeActiveConnections();
|
|
updateIcons();
|
|
}
|
|
|
|
bool Network::isEnabled() const
|
|
{
|
|
return NetworkManager::isNetworkingEnabled();
|
|
}
|
|
|
|
void Network::setEnabled(bool enabled)
|
|
{
|
|
NetworkManager::setNetworkingEnabled(enabled);
|
|
}
|
|
|
|
bool Network::isWirelessEnabled() const
|
|
{
|
|
return NetworkManager::isWirelessEnabled();
|
|
}
|
|
|
|
void Network::setWirelessEnabled(bool enabled)
|
|
{
|
|
NetworkManager::setWirelessEnabled(enabled);
|
|
}
|
|
|
|
bool Network::isWirelessHardwareEnabled() const
|
|
{
|
|
return NetworkManager::isWirelessHardwareEnabled();
|
|
}
|
|
|
|
QString Network::wirelessConnectionName() const
|
|
{
|
|
return m_wirelessConnectionName;
|
|
}
|
|
|
|
QString Network::wirelessIconName() const
|
|
{
|
|
return m_wirelessIconName;
|
|
}
|
|
|
|
Network::SortedConnectionType Network::connectionTypeToSortedType(NetworkManager::ConnectionSettings::ConnectionType type)
|
|
{
|
|
switch (type) {
|
|
case NetworkManager::ConnectionSettings::Adsl:
|
|
return Network::Adsl;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Bluetooth:
|
|
return Network::Bluetooth;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Cdma:
|
|
return Network::Cdma;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Gsm:
|
|
return Network::Gsm;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Infiniband:
|
|
return Network::Infiniband;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::OLPCMesh:
|
|
return Network::OLPCMesh;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Pppoe:
|
|
return Network::Pppoe;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Vpn:
|
|
return Network::Vpn;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Wired:
|
|
return Network::Wired;
|
|
break;
|
|
case NetworkManager::ConnectionSettings::Wireless:
|
|
return Network::Wireless;
|
|
break;
|
|
default:
|
|
return Network::Other;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Network::statusChanged(NetworkManager::Status status)
|
|
{
|
|
if (status == NetworkManager::ConnectedLinkLocal ||
|
|
status == NetworkManager::ConnectedSiteOnly ||
|
|
status == NetworkManager::Connected) {
|
|
changeActiveConnections();
|
|
}
|
|
|
|
if (status == NetworkManager::Disconnected) {
|
|
resetWireless();
|
|
}
|
|
}
|
|
|
|
void Network::changeActiveConnections()
|
|
{
|
|
if (NetworkManager::status() != NetworkManager::Connected &&
|
|
NetworkManager::status() != NetworkManager::ConnectedLinkLocal &&
|
|
NetworkManager::status() != NetworkManager::ConnectedSiteOnly) {
|
|
|
|
m_wirelessConnectionName = "";
|
|
emit wirelessConnectionNameChanged();
|
|
|
|
return;
|
|
}
|
|
|
|
QString activeConnections;
|
|
QList<NetworkManager::ActiveConnection::Ptr> activeConnectionList = NetworkManager::activeConnections();
|
|
std::sort(activeConnectionList.begin(), activeConnectionList.end(), [](const NetworkManager::ActiveConnection::Ptr &left, const NetworkManager::ActiveConnection::Ptr &right) {
|
|
return Network::connectionTypeToSortedType(left->type()) < Network::connectionTypeToSortedType(right->type());
|
|
});
|
|
|
|
for (const NetworkManager::ActiveConnection::Ptr &active : activeConnectionList) {
|
|
if (active->devices().isEmpty() && !UiUtils::isConnectionTypeSupported(active->type()))
|
|
continue;
|
|
|
|
NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(active->devices().first());
|
|
NetworkManager::Connection::Ptr connection = active->connection();
|
|
bool connecting = false;
|
|
bool connected = false;
|
|
|
|
if (active->state() == NetworkManager::ActiveConnection::Activated)
|
|
connected = true;
|
|
else if (active->state() == NetworkManager::ActiveConnection::Activating)
|
|
connecting = true;
|
|
|
|
if (device->type() == NetworkManager::Device::Wifi) {
|
|
if (m_wirelessConnectionName != connection->name()) {
|
|
m_wirelessConnectionName = connection->name();
|
|
emit wirelessConnectionNameChanged();
|
|
|
|
updateIcons();
|
|
}
|
|
}
|
|
|
|
connect(connection.data(), &NetworkManager::Connection::updated, this, &Network::changeActiveConnections, Qt::UniqueConnection);
|
|
}
|
|
}
|
|
|
|
void Network::activatingConnectionChanged()
|
|
{
|
|
updateIcons();
|
|
}
|
|
|
|
void Network::defaultChanged()
|
|
{
|
|
statusChanged(NetworkManager::status());
|
|
}
|
|
|
|
void Network::onWirelessEnabledChanged()
|
|
{
|
|
if (!isWirelessEnabled()) {
|
|
resetWireless();
|
|
} else {
|
|
updateIcons();
|
|
}
|
|
|
|
emit wirelessEnabledChanged();
|
|
}
|
|
|
|
void Network::onWirelessNetworkAppeared(const QString& network)
|
|
{
|
|
Q_UNUSED(network);
|
|
|
|
updateIcons();
|
|
}
|
|
|
|
void Network::updateIcons()
|
|
{
|
|
if (m_wirelessNetwork) {
|
|
disconnect(m_wirelessNetwork.data(), nullptr, this, nullptr);
|
|
m_wirelessNetwork.clear();
|
|
}
|
|
|
|
NetworkManager::ActiveConnection::Ptr connection = NetworkManager::activatingConnection();
|
|
|
|
// Set icon based on the current primary connection if the activating connection is virtual
|
|
// since we're not setting icons for virtual connections
|
|
if (!connection
|
|
|| (connection && UiUtils::isConnectionTypeVirtual(connection->type()))
|
|
|| connection->type() == NetworkManager::ConnectionSettings::WireGuard) {
|
|
connection = NetworkManager::primaryConnection();
|
|
}
|
|
|
|
/* Fallback: If we still don't have an active connection with default route or the default route goes through a connection
|
|
of generic type (some type of VPNs) we need to go through all other active connections and pick the one with
|
|
highest probability of being the main one (order is: vpn, wired, wireless, gsm, cdma, bluetooth) */
|
|
if ((!connection && !NetworkManager::activeConnections().isEmpty()) || (connection && connection->type() == NetworkManager::ConnectionSettings::Generic)
|
|
|| (connection && connection->type() == NetworkManager::ConnectionSettings::Tun)) {
|
|
for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) {
|
|
const NetworkManager::ConnectionSettings::ConnectionType type = activeConnection->type();
|
|
if (type == NetworkManager::ConnectionSettings::Bluetooth) {
|
|
if (connection && connection->type() <= NetworkManager::ConnectionSettings::Bluetooth) {
|
|
connection = activeConnection;
|
|
}
|
|
} else if (type == NetworkManager::ConnectionSettings::Cdma) {
|
|
if (connection && connection->type() <= NetworkManager::ConnectionSettings::Cdma) {
|
|
connection = activeConnection;
|
|
}
|
|
} else if (type == NetworkManager::ConnectionSettings::Gsm) {
|
|
if (connection && connection->type() <= NetworkManager::ConnectionSettings::Gsm) {
|
|
connection = activeConnection;
|
|
}
|
|
} else if (type == NetworkManager::ConnectionSettings::Vpn) {
|
|
connection = activeConnection;
|
|
} else if (type == NetworkManager::ConnectionSettings::WireGuard) {
|
|
connection = activeConnection;
|
|
} else if (type == NetworkManager::ConnectionSettings::Wired) {
|
|
if (connection && (connection->type() != NetworkManager::ConnectionSettings::Vpn
|
|
|| connection->type() != NetworkManager::ConnectionSettings::WireGuard)) {
|
|
connection = activeConnection;
|
|
}
|
|
} else if (type == NetworkManager::ConnectionSettings::Wireless) {
|
|
if (connection && (connection->type() != NetworkManager::ConnectionSettings::Vpn &&
|
|
(connection->type() != NetworkManager::ConnectionSettings::Wired))) {
|
|
connection = activeConnection;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (connection && !connection->devices().isEmpty()) {
|
|
NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(connection->devices().first());
|
|
|
|
if (device) {
|
|
NetworkManager::Device::Type type = device->type();
|
|
|
|
if (type == NetworkManager::Device::Wifi) {
|
|
NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>();
|
|
|
|
if (wifiDevice->mode() == NetworkManager::WirelessDevice::Adhoc) {
|
|
updateWirelessIconForSignalStrength(100);
|
|
} else {
|
|
NetworkManager::AccessPoint::Ptr ap = wifiDevice->activeAccessPoint();
|
|
if (ap) {
|
|
updateWirelessIcon(device, ap->ssid());
|
|
}
|
|
}
|
|
} else if (type == NetworkManager::Device::Ethernet) {
|
|
|
|
} else {
|
|
resetWireless();
|
|
}
|
|
} else {
|
|
resetWireless();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Network::updateWirelessIcon(const NetworkManager::Device::Ptr &device, const QString& ssid)
|
|
{
|
|
NetworkManager::WirelessDevice::Ptr wirelessDevice = device.objectCast<NetworkManager::WirelessDevice>();
|
|
|
|
if (device) {
|
|
m_wirelessNetwork = wirelessDevice->findNetwork(ssid);
|
|
} else {
|
|
m_wirelessNetwork.clear();
|
|
}
|
|
|
|
if (m_wirelessNetwork) {
|
|
connect(m_wirelessNetwork.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &Network::updateWirelessIconForSignalStrength, Qt::UniqueConnection);
|
|
updateWirelessIconForSignalStrength(m_wirelessNetwork->signalStrength());
|
|
} else {
|
|
resetWireless();
|
|
}
|
|
}
|
|
|
|
void Network::updateWirelessIconForSignalStrength(int strength)
|
|
{
|
|
int iconStrength = 0;
|
|
|
|
if (strength == 0)
|
|
iconStrength = 0;
|
|
else if (strength <= 25)
|
|
iconStrength = 25;
|
|
else if (strength <= 50)
|
|
iconStrength = 50;
|
|
else if (strength <= 75)
|
|
iconStrength = 75;
|
|
else if (strength <= 100)
|
|
iconStrength = 100;
|
|
|
|
m_wirelessIconName = QString("network-wireless-connected-%1").arg(iconStrength);
|
|
emit wirelessIconNameChanged();
|
|
}
|
|
|
|
void Network::resetWireless()
|
|
{
|
|
m_wirelessConnectionName = "";
|
|
m_wirelessIconName = "";
|
|
|
|
emit wirelessConnectionNameChanged();
|
|
emit wirelessIconNameChanged();
|
|
}
|