File indexing completed on 2023-11-26 08:54:35
0001 /* 0002 SPDX-FileCopyrightText: 2013-2018 Jan Grulich <jgrulich@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 "networkmodel.h" 0008 #include "configuration.h" 0009 #include "networkmodelitem.h" 0010 #include "plasma_nm_libs.h" 0011 #include "uiutils.h" 0012 #include <QVector> 0013 #include <algorithm> 0014 0015 #include <ModemManagerQt/Manager> 0016 0017 #include <NetworkManagerQt/GenericDevice> 0018 #include <NetworkManagerQt/Settings> 0019 0020 NetworkModel::NetworkModel(QObject *parent) 0021 : QAbstractListModel(parent) 0022 { 0023 QLoggingCategory::setFilterRules(QStringLiteral("plasma-nm.debug = false")); 0024 0025 initialize(); 0026 } 0027 0028 NetworkModel::~NetworkModel() = default; 0029 0030 QVariant NetworkModel::data(const QModelIndex &index, int role) const 0031 { 0032 const int row = index.row(); 0033 0034 if (row >= 0 && row < m_list.count()) { 0035 NetworkModelItem *item = m_list.itemAt(row); 0036 0037 switch (role) { 0038 case ConnectionDetailsRole: 0039 return item->details(); 0040 case ConnectionIconRole: 0041 return item->icon(); 0042 case ConnectionPathRole: 0043 return item->connectionPath(); 0044 case ConnectionStateRole: 0045 return item->connectionState(); 0046 case DeviceName: 0047 return item->deviceName(); 0048 case DevicePathRole: 0049 return item->devicePath(); 0050 case DeviceStateRole: 0051 return item->deviceState(); 0052 case DuplicateRole: 0053 return item->duplicate(); 0054 case ItemUniqueNameRole: 0055 if (m_list.returnItems(NetworkItemsList::Name, item->name()).count() > 1) { 0056 return item->originalName(); 0057 } else { 0058 return item->name(); 0059 } 0060 case ItemTypeRole: 0061 return item->itemType(); 0062 case LastUsedRole: 0063 return UiUtils::formatLastUsedDateRelative(item->timestamp()); 0064 case LastUsedDateOnlyRole: 0065 return UiUtils::formatDateRelative(item->timestamp()); 0066 case NameRole: 0067 return item->name(); 0068 case SectionRole: 0069 return item->sectionType(); 0070 case SignalRole: 0071 return item->signal(); 0072 case SlaveRole: 0073 return item->slave(); 0074 case SsidRole: 0075 return item->ssid(); 0076 case SpecificPathRole: 0077 return item->specificPath(); 0078 case SecurityTypeRole: 0079 return item->securityType(); 0080 case SecurityTypeStringRole: 0081 return UiUtils::labelFromWirelessSecurity(item->securityType()); 0082 case TimeStampRole: 0083 return item->timestamp(); 0084 case TypeRole: 0085 return item->type(); 0086 case UniRole: 0087 return item->uni(); 0088 case UuidRole: 0089 return item->uuid(); 0090 case VpnState: 0091 return item->vpnState(); 0092 case VpnType: 0093 return item->vpnType(); 0094 case RxBytesRole: 0095 return item->rxBytes(); 0096 case TxBytesRole: 0097 return item->txBytes(); 0098 case DelayModelUpdatesRole: 0099 return item->delayModelUpdates(); 0100 case Qt::AccessibleDescriptionRole: 0101 return item->accessibleDescription(); 0102 default: 0103 break; 0104 } 0105 } 0106 0107 return {}; 0108 } 0109 0110 bool NetworkModel::setData(const QModelIndex &index, const QVariant &value, int role) 0111 { 0112 const int row = index.row(); 0113 const bool delay = value.toBool(); 0114 0115 if (row >= 0 && row < m_list.count() && role == DelayModelUpdatesRole) { 0116 NetworkModelItem *item = m_list.itemAt(row); 0117 if (item->delayModelUpdates() != delay) { 0118 item->setDelayModelUpdates(delay); 0119 dataChanged(index, index, QVector<int>{DelayModelUpdatesRole}); 0120 updateDelayModelUpdates(); 0121 return true; 0122 } 0123 } 0124 return false; 0125 } 0126 0127 int NetworkModel::rowCount(const QModelIndex &parent) const 0128 { 0129 Q_UNUSED(parent); 0130 return parent.isValid() ? 0 : m_list.count(); 0131 } 0132 0133 QHash<int, QByteArray> NetworkModel::roleNames() const 0134 { 0135 QHash<int, QByteArray> roles = QAbstractListModel::roleNames(); 0136 roles[ConnectionDetailsRole] = "ConnectionDetails"; 0137 roles[ConnectionIconRole] = "ConnectionIcon"; 0138 roles[ConnectionPathRole] = "ConnectionPath"; 0139 roles[ConnectionStateRole] = "ConnectionState"; 0140 roles[DeviceName] = "DeviceName"; 0141 roles[DevicePathRole] = "DevicePath"; 0142 roles[DeviceStateRole] = "DeviceState"; 0143 roles[DuplicateRole] = "Duplicate"; 0144 roles[ItemUniqueNameRole] = "ItemUniqueName"; 0145 roles[ItemTypeRole] = "ItemType"; 0146 roles[LastUsedRole] = "LastUsed"; 0147 roles[LastUsedDateOnlyRole] = "LastUsedDateOnly"; 0148 roles[NameRole] = "Name"; 0149 roles[SectionRole] = "Section"; 0150 roles[SignalRole] = "Signal"; 0151 roles[SlaveRole] = "Slave"; 0152 roles[SsidRole] = "Ssid"; 0153 roles[SpecificPathRole] = "SpecificPath"; 0154 roles[SecurityTypeRole] = "SecurityType"; 0155 roles[SecurityTypeStringRole] = "SecurityTypeString"; 0156 roles[TimeStampRole] = "TimeStamp"; 0157 roles[TypeRole] = "Type"; 0158 roles[Qt::AccessibleDescriptionRole] = "AccessibleDescription"; 0159 roles[UniRole] = "Uni"; 0160 roles[UuidRole] = "Uuid"; 0161 roles[VpnState] = "VpnState"; 0162 roles[VpnType] = "VpnType"; 0163 roles[RxBytesRole] = "RxBytes"; 0164 roles[TxBytesRole] = "TxBytes"; 0165 roles[DelayModelUpdatesRole] = "DelayModelUpdates"; 0166 0167 return roles; 0168 } 0169 0170 bool NetworkModel::delayModelUpdates() const 0171 { 0172 return m_delayModelUpdates; 0173 } 0174 0175 void NetworkModel::updateDelayModelUpdates() 0176 { 0177 const QList<NetworkModelItem *> items = m_list.items(); 0178 const bool delay = std::any_of(items.begin(), items.end(), [](NetworkModelItem *item) -> bool { 0179 return item->delayModelUpdates(); 0180 }); 0181 if (m_delayModelUpdates != delay) { 0182 m_delayModelUpdates = delay; 0183 Q_EMIT delayModelUpdatesChanged(); 0184 0185 if (!m_delayModelUpdates) { 0186 flushUpdateQueue(); 0187 } 0188 } 0189 } 0190 0191 void NetworkModel::flushUpdateQueue() 0192 { 0193 while (!m_updateQueue.isEmpty()) { 0194 QPair<NetworkModel::ModelChangeType, NetworkModelItem *> update = m_updateQueue.dequeue(); 0195 if (update.first == ItemAdded) { 0196 insertItem(update.second); 0197 } else if (update.first == ItemRemoved) { 0198 removeItem(update.second); 0199 } else if (update.first == ItemPropertyChanged) { 0200 updateItem(update.second); 0201 } 0202 } 0203 } 0204 0205 void NetworkModel::initialize() 0206 { 0207 // Initialize existing connections 0208 for (const NetworkManager::Connection::Ptr &connection : NetworkManager::listConnections()) { 0209 addConnection(connection); 0210 } 0211 0212 // Initialize existing devices 0213 for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { 0214 if (!dev->managed()) { 0215 continue; 0216 } 0217 // TODO implement loopback device in NetowrkManagerQt 0218 if (dev->interfaceName() == QLatin1String("lo")) { 0219 continue; 0220 } 0221 addDevice(dev); 0222 } 0223 0224 // Initialize existing active connections 0225 for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) { 0226 addActiveConnection(active); 0227 } 0228 0229 initializeSignals(); 0230 } 0231 0232 void NetworkModel::initializeSignals() 0233 { 0234 connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &NetworkModel::activeConnectionAdded, Qt::UniqueConnection); 0235 connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionRemoved, this, &NetworkModel::activeConnectionRemoved, Qt::UniqueConnection); 0236 connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionAdded, this, &NetworkModel::connectionAdded, Qt::UniqueConnection); 0237 connect(NetworkManager::settingsNotifier(), 0238 &NetworkManager::SettingsNotifier::connectionRemoved, 0239 this, 0240 &NetworkModel::connectionRemoved, 0241 Qt::UniqueConnection); 0242 connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &NetworkModel::deviceAdded, Qt::UniqueConnection); 0243 connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &NetworkModel::deviceRemoved, Qt::UniqueConnection); 0244 connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &NetworkModel::statusChanged, Qt::UniqueConnection); 0245 } 0246 0247 void NetworkModel::initializeSignals(const NetworkManager::ActiveConnection::Ptr &activeConnection) 0248 { 0249 if (activeConnection->vpn()) { 0250 NetworkManager::VpnConnection::Ptr vpnConnection = activeConnection.objectCast<NetworkManager::VpnConnection>(); 0251 if (vpnConnection) { 0252 connect(vpnConnection.data(), 0253 &NetworkManager::VpnConnection::stateChanged, 0254 this, 0255 &NetworkModel::activeVpnConnectionStateChanged, 0256 Qt::UniqueConnection); 0257 } 0258 } else { 0259 connect(activeConnection.data(), 0260 &NetworkManager::ActiveConnection::stateChanged, 0261 this, 0262 &NetworkModel::activeConnectionStateChanged, 0263 Qt::UniqueConnection); 0264 } 0265 } 0266 0267 void NetworkModel::initializeSignals(const NetworkManager::Connection::Ptr &connection) 0268 { 0269 connect(connection.data(), &NetworkManager::Connection::updated, this, &NetworkModel::connectionUpdated, Qt::UniqueConnection); 0270 } 0271 0272 void NetworkModel::initializeSignals(const NetworkManager::Device::Ptr &device) 0273 { 0274 connect(device.data(), &NetworkManager::Device::availableConnectionAppeared, this, &NetworkModel::availableConnectionAppeared, Qt::UniqueConnection); 0275 connect(device.data(), &NetworkManager::Device::availableConnectionDisappeared, this, &NetworkModel::availableConnectionDisappeared, Qt::UniqueConnection); 0276 connect(device.data(), &NetworkManager::Device::ipV4ConfigChanged, this, &NetworkModel::ipConfigChanged, Qt::UniqueConnection); 0277 connect(device.data(), &NetworkManager::Device::ipV6ConfigChanged, this, &NetworkModel::ipConfigChanged, Qt::UniqueConnection); 0278 connect(device.data(), &NetworkManager::Device::ipInterfaceChanged, this, &NetworkModel::ipInterfaceChanged); 0279 connect(device.data(), &NetworkManager::Device::stateChanged, this, &NetworkModel::deviceStateChanged, Qt::UniqueConnection); 0280 0281 auto deviceStatistics = device->deviceStatistics(); 0282 connect(deviceStatistics.data(), &NetworkManager::DeviceStatistics::rxBytesChanged, this, [this, device](qulonglong rxBytes) { 0283 for (auto item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { 0284 item->setRxBytes(rxBytes); 0285 updateItem(item); 0286 } 0287 }); 0288 connect(deviceStatistics.data(), &NetworkManager::DeviceStatistics::txBytesChanged, this, [this, device](qulonglong txBytes) { 0289 for (auto item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { 0290 item->setTxBytes(txBytes); 0291 updateItem(item); 0292 } 0293 }); 0294 0295 if (device->type() == NetworkManager::Device::Wifi) { 0296 NetworkManager::WirelessDevice::Ptr wifiDev = device.objectCast<NetworkManager::WirelessDevice>(); 0297 connect(wifiDev.data(), &NetworkManager::WirelessDevice::networkAppeared, this, &NetworkModel::wirelessNetworkAppeared, Qt::UniqueConnection); 0298 connect(wifiDev.data(), &NetworkManager::WirelessDevice::networkDisappeared, this, &NetworkModel::wirelessNetworkDisappeared, Qt::UniqueConnection); 0299 0300 } else if (device->type() == NetworkManager::Device::Modem) { 0301 ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(device->udi()); 0302 if (modem) { 0303 if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { 0304 ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>(); 0305 if (modemNetwork) { 0306 connect(modemNetwork.data(), 0307 &ModemManager::Modem::signalQualityChanged, 0308 this, 0309 &NetworkModel::gsmNetworkSignalQualityChanged, 0310 Qt::UniqueConnection); 0311 connect(modemNetwork.data(), 0312 &ModemManager::Modem::accessTechnologiesChanged, 0313 this, 0314 &NetworkModel::gsmNetworkAccessTechnologiesChanged, 0315 Qt::UniqueConnection); 0316 connect(modemNetwork.data(), 0317 &ModemManager::Modem::currentModesChanged, 0318 this, 0319 &NetworkModel::gsmNetworkCurrentModesChanged, 0320 Qt::UniqueConnection); 0321 } 0322 } 0323 } 0324 } 0325 } 0326 0327 void NetworkModel::initializeSignals(const NetworkManager::WirelessNetwork::Ptr &network) 0328 { 0329 connect(network.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &NetworkModel::wirelessNetworkSignalChanged, Qt::UniqueConnection); 0330 connect(network.data(), 0331 &NetworkManager::WirelessNetwork::referenceAccessPointChanged, 0332 this, 0333 &NetworkModel::wirelessNetworkReferenceApChanged, 0334 Qt::UniqueConnection); 0335 } 0336 0337 void NetworkModel::addActiveConnection(const NetworkManager::ActiveConnection::Ptr &activeConnection) 0338 { 0339 initializeSignals(activeConnection); 0340 0341 NetworkManager::Device::Ptr device; 0342 NetworkManager::Connection::Ptr connection = activeConnection->connection(); 0343 0344 // Not necessary to have device for VPN connections 0345 if (activeConnection && !activeConnection->vpn() && !activeConnection->devices().isEmpty()) { 0346 device = NetworkManager::findNetworkInterface(activeConnection->devices().first()); 0347 } 0348 0349 // Check whether we have a base connection 0350 if (!m_list.contains(NetworkItemsList::Uuid, connection->uuid())) { 0351 // Active connection appeared before a base connection, so we have to add its base connection first 0352 addConnection(connection); 0353 } 0354 0355 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::NetworkItemsList::Uuid, connection->uuid())) { 0356 if (((device && device->uni() == item->devicePath()) || item->devicePath().isEmpty()) || item->type() == NetworkManager::ConnectionSettings::Vpn) { 0357 item->setActiveConnectionPath(activeConnection->path()); 0358 item->setConnectionState(activeConnection->state()); 0359 if (activeConnection->vpn()) { 0360 NetworkManager::VpnConnection::Ptr vpnConnection = activeConnection.objectCast<NetworkManager::VpnConnection>(); 0361 NetworkManager::VpnConnection::State state = vpnConnection->state(); 0362 if (state == NetworkManager::VpnConnection::Prepare // 0363 || state == NetworkManager::VpnConnection::NeedAuth // 0364 || state == NetworkManager::VpnConnection::Connecting // 0365 || state == NetworkManager::VpnConnection::GettingIpConfig) { 0366 item->setConnectionState(NetworkManager::ActiveConnection::Activating); 0367 } else if (state == NetworkManager::VpnConnection::Activated) { 0368 item->setConnectionState(NetworkManager::ActiveConnection::Activated); 0369 } else { 0370 item->setConnectionState(NetworkManager::ActiveConnection::Deactivated); 0371 } 0372 item->setVpnState(state); 0373 } 0374 item->invalidateDetails(); 0375 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": active connection state changed to " << item->connectionState(); 0376 0377 if (device && device->uni() == item->devicePath()) { 0378 auto deviceStatistics = device->deviceStatistics(); 0379 if (deviceStatistics->refreshRateMs() != 0) { 0380 item->setRxBytes(deviceStatistics->rxBytes()); 0381 item->setTxBytes(deviceStatistics->txBytes()); 0382 } 0383 } 0384 } 0385 updateItem(item); 0386 } 0387 } 0388 0389 void NetworkModel::addAvailableConnection(const QString &connection, const NetworkManager::Device::Ptr &device) 0390 { 0391 if (!device) { 0392 return; 0393 } 0394 0395 checkAndCreateDuplicate(connection, device->uni()); 0396 0397 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { 0398 // The item is already associated with another device 0399 if (!device || !item->devicePath().isEmpty()) { 0400 continue; 0401 } 0402 0403 if (device->ipInterfaceName().isEmpty()) { 0404 item->setDeviceName(device->interfaceName()); 0405 } else { 0406 item->setDeviceName(device->ipInterfaceName()); 0407 } 0408 0409 item->setDevicePath(device->uni()); 0410 item->setDeviceState(device->state()); 0411 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": device changed to " << item->devicePath(); 0412 if (device->type() == NetworkManager::Device::Modem) { 0413 ModemManager::ModemDevice::Ptr modemDevice = ModemManager::findModemDevice(device->udi()); 0414 if (modemDevice) { 0415 ModemManager::Modem::Ptr modemInterface = modemDevice->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>(); 0416 if (modemInterface) { 0417 item->setSignal(modemInterface->signalQuality().signal); 0418 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": signal changed to " << item->signal(); 0419 } 0420 } 0421 } 0422 0423 if (item->type() == NetworkManager::ConnectionSettings::Wireless && item->mode() == NetworkManager::WirelessSetting::Infrastructure) { 0424 // Find an accesspoint which could be removed, because it will be merged with a connection 0425 for (NetworkModelItem *secondItem : m_list.returnItems(NetworkItemsList::Ssid, item->ssid())) { 0426 if (secondItem->itemType() == NetworkModelItem::AvailableAccessPoint && secondItem->devicePath() == item->devicePath()) { 0427 removeItem(secondItem); 0428 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Access point " << secondItem->name() << ": merged to " << item->name() << " connection"; 0429 break; 0430 } 0431 } 0432 0433 NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>(); 0434 if (wifiDevice) { 0435 NetworkManager::WirelessNetwork::Ptr wifiNetwork = wifiDevice->findNetwork(item->ssid()); 0436 if (wifiNetwork) { 0437 updateFromWirelessNetwork(item, wifiNetwork, wifiDevice); 0438 } 0439 } 0440 } 0441 0442 updateItem(item); 0443 break; 0444 } 0445 } 0446 0447 void NetworkModel::addConnection(const NetworkManager::Connection::Ptr &connection) 0448 { 0449 // Can't add a connection without name or uuid 0450 if (connection->name().isEmpty() || connection->uuid().isEmpty()) { 0451 return; 0452 } 0453 0454 initializeSignals(connection); 0455 0456 NetworkManager::ConnectionSettings::Ptr settings = connection->settings(); 0457 NetworkManager::VpnSetting::Ptr vpnSetting; 0458 NetworkManager::WirelessSetting::Ptr wirelessSetting; 0459 0460 if (settings->connectionType() == NetworkManager::ConnectionSettings::Vpn) { 0461 vpnSetting = settings->setting(NetworkManager::Setting::Vpn).dynamicCast<NetworkManager::VpnSetting>(); 0462 } else if (settings->connectionType() == NetworkManager::ConnectionSettings::Wireless) { 0463 wirelessSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>(); 0464 } 0465 0466 // Check whether the connection is already in the model to avoid duplicates, but this shouldn't happen 0467 if (m_list.contains(NetworkItemsList::Connection, connection->path())) { 0468 return; 0469 } 0470 0471 auto item = new NetworkModelItem(); 0472 item->setConnectionPath(connection->path()); 0473 item->setName(settings->id()); 0474 item->setTimestamp(settings->timestamp()); 0475 item->setType(settings->connectionType()); 0476 item->setUuid(settings->uuid()); 0477 item->setSlave(settings->isSlave()); 0478 0479 if (item->type() == NetworkManager::ConnectionSettings::Vpn) { 0480 item->setVpnType(vpnSetting->serviceType().section('.', -1)); 0481 } else if (item->type() == NetworkManager::ConnectionSettings::Wireless) { 0482 item->setMode(wirelessSetting->mode()); 0483 item->setSecurityType(NetworkManager::securityTypeFromConnectionSetting(settings)); 0484 item->setSsid(QString::fromUtf8(wirelessSetting->ssid())); 0485 } 0486 0487 item->invalidateDetails(); 0488 0489 insertItem(item); 0490 qCDebug(PLASMA_NM_LIBS_LOG) << "New connection" << item->name() << "added"; 0491 } 0492 0493 void NetworkModel::addDevice(const NetworkManager::Device::Ptr &device) 0494 { 0495 initializeSignals(device); 0496 0497 if (device->type() == NetworkManager::Device::Wifi) { 0498 NetworkManager::WirelessDevice::Ptr wifiDev = device.objectCast<NetworkManager::WirelessDevice>(); 0499 for (const NetworkManager::WirelessNetwork::Ptr &wifiNetwork : wifiDev->networks()) { 0500 addWirelessNetwork(wifiNetwork, wifiDev); 0501 } 0502 } 0503 0504 for (const NetworkManager::Connection::Ptr &connection : device->availableConnections()) { 0505 addAvailableConnection(connection->path(), device); 0506 } 0507 } 0508 0509 void NetworkModel::addWirelessNetwork(const NetworkManager::WirelessNetwork::Ptr &network, const NetworkManager::WirelessDevice::Ptr &device) 0510 { 0511 initializeSignals(network); 0512 0513 // Avoid duplicating entries in the model 0514 if (!Configuration::self().hotspotConnectionPath().isEmpty()) { 0515 NetworkManager::ActiveConnection::Ptr activeConnection = NetworkManager::findActiveConnection(Configuration::self().hotspotConnectionPath()); 0516 0517 // If we are trying to add an AP which is the one created by our hotspot, then we can skip this and don't add it twice 0518 if (activeConnection && activeConnection->specificObject() == network->referenceAccessPoint()->uni()) { 0519 return; 0520 } 0521 } 0522 0523 // BUG: 386342 0524 // When creating a new hidden wireless network and attempting to connect to it, NM then later reports that AccessPoint appeared, but 0525 // it doesn't know its SSID from some reason, this also makes Wireless device to advertise a new available connection, which we later 0526 // attempt to merge with an AP, based on its SSID, but it doesn't find any, because we have AP with empty SSID. After this we get another 0527 // AccessPoint appeared signal, this time we know SSID, but we don't attempt any merging, because it's usually the other way around, thus 0528 // we need to attempt to merge it here with a connection we guess it's related to this new AP 0529 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Type, NetworkManager::ConnectionSettings::Wireless)) { 0530 if (item->itemType() != NetworkModelItem::AvailableConnection) 0531 continue; 0532 0533 NetworkManager::ConnectionSettings::Ptr connectionSettings = NetworkManager::findConnection(item->connectionPath())->settings(); 0534 if (connectionSettings && connectionSettings->connectionType() == NetworkManager::ConnectionSettings::Wireless) { 0535 NetworkManager::WirelessSetting::Ptr wirelessSetting = 0536 connectionSettings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>(); 0537 if (QString::fromUtf8(wirelessSetting->ssid()) == network->ssid()) { 0538 const QString bssid = NetworkManager::macAddressAsString(wirelessSetting->bssid()); 0539 const QString restrictedHw = NetworkManager::macAddressAsString(wirelessSetting->macAddress()); 0540 if ((bssid.isEmpty() || bssid == network->referenceAccessPoint()->hardwareAddress()) 0541 && (restrictedHw.isEmpty() || restrictedHw == device->hardwareAddress())) { 0542 updateFromWirelessNetwork(item, network, device); 0543 return; 0544 } 0545 } 0546 } 0547 } 0548 0549 NetworkManager::WirelessSetting::NetworkMode mode = NetworkManager::WirelessSetting::Infrastructure; 0550 NetworkManager::WirelessSecurityType securityType = NetworkManager::UnknownSecurity; 0551 0552 NetworkManager::AccessPoint::Ptr ap = network->referenceAccessPoint(); 0553 if (ap && (ap->capabilities().testFlag(NetworkManager::AccessPoint::Privacy) || ap->wpaFlags() || ap->rsnFlags())) { 0554 securityType = NetworkManager::findBestWirelessSecurity(device->wirelessCapabilities(), 0555 true, 0556 (device->mode() == NetworkManager::WirelessDevice::Adhoc), 0557 ap->capabilities(), 0558 ap->wpaFlags(), 0559 ap->rsnFlags()); 0560 if (network->referenceAccessPoint()->mode() == NetworkManager::AccessPoint::Infra) { 0561 mode = NetworkManager::WirelessSetting::Infrastructure; 0562 } else if (network->referenceAccessPoint()->mode() == NetworkManager::AccessPoint::Adhoc) { 0563 mode = NetworkManager::WirelessSetting::Adhoc; 0564 } else if (network->referenceAccessPoint()->mode() == NetworkManager::AccessPoint::ApMode) { 0565 mode = NetworkManager::WirelessSetting::Ap; 0566 } 0567 } 0568 0569 auto item = new NetworkModelItem(); 0570 if (device->ipInterfaceName().isEmpty()) { 0571 item->setDeviceName(device->interfaceName()); 0572 } else { 0573 item->setDeviceName(device->ipInterfaceName()); 0574 } 0575 item->setDevicePath(device->uni()); 0576 item->setMode(mode); 0577 item->setName(network->ssid()); 0578 item->setSignal(network->signalStrength()); 0579 item->setSpecificPath(network->referenceAccessPoint()->uni()); 0580 item->setSsid(network->ssid()); 0581 item->setType(NetworkManager::ConnectionSettings::Wireless); 0582 item->setSecurityType(securityType); 0583 item->invalidateDetails(); 0584 0585 insertItem(item); 0586 qCDebug(PLASMA_NM_LIBS_LOG) << "New wireless network" << item->name() << "added"; 0587 } 0588 0589 void NetworkModel::checkAndCreateDuplicate(const QString &connection, const QString &deviceUni) 0590 { 0591 bool createDuplicate = false; 0592 NetworkModelItem *originalItem = nullptr; 0593 0594 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { 0595 if (!item->duplicate()) { 0596 originalItem = item; 0597 } 0598 0599 if (!item->duplicate() && item->itemType() == NetworkModelItem::AvailableConnection 0600 && (item->devicePath() != deviceUni && !item->devicePath().isEmpty())) { 0601 createDuplicate = true; 0602 } 0603 } 0604 0605 if (createDuplicate) { 0606 auto duplicatedItem = new NetworkModelItem(originalItem); 0607 duplicatedItem->invalidateDetails(); 0608 0609 insertItem(duplicatedItem); 0610 } 0611 } 0612 0613 void NetworkModel::onItemUpdated() 0614 { 0615 auto item = static_cast<NetworkModelItem *>(sender()); 0616 if (item) { 0617 updateItem(item); 0618 } 0619 } 0620 0621 void NetworkModel::setDeviceStatisticsRefreshRateMs(const QString &devicePath, uint refreshRate) 0622 { 0623 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(devicePath); 0624 0625 if (device) { 0626 device->deviceStatistics()->setRefreshRateMs(refreshRate); 0627 } 0628 } 0629 0630 void NetworkModel::insertItem(NetworkModelItem *item) 0631 { 0632 if (m_delayModelUpdates) { 0633 m_updateQueue.enqueue(QPair<NetworkModel::ModelChangeType, NetworkModelItem *>(NetworkModel::ItemAdded, item)); 0634 return; 0635 } 0636 0637 const int index = m_list.count(); 0638 beginInsertRows(QModelIndex(), index, index); 0639 m_list.insertItem(item); 0640 endInsertRows(); 0641 updateDelayModelUpdates(); 0642 } 0643 0644 void NetworkModel::removeItem(NetworkModelItem *item) 0645 { 0646 if (m_delayModelUpdates) { 0647 m_updateQueue.enqueue(QPair<NetworkModel::ModelChangeType, NetworkModelItem *>(NetworkModel::ItemRemoved, item)); 0648 return; 0649 } 0650 0651 const int row = m_list.indexOf(item); 0652 if (row != -1) { 0653 beginRemoveRows(QModelIndex(), row, row); 0654 m_list.removeItem(item); 0655 item->deleteLater(); 0656 endRemoveRows(); 0657 updateDelayModelUpdates(); 0658 } 0659 } 0660 0661 void NetworkModel::updateItem(NetworkModelItem *item) 0662 { 0663 if (m_delayModelUpdates) { 0664 m_updateQueue.enqueue(QPair<NetworkModel::ModelChangeType, NetworkModelItem *>(NetworkModel::ItemPropertyChanged, item)); 0665 return; 0666 } 0667 0668 const int row = m_list.indexOf(item); 0669 if (row != -1) { 0670 item->invalidateDetails(); 0671 QModelIndex index = createIndex(row, 0); 0672 Q_EMIT dataChanged(index, index, item->changedRoles()); 0673 item->clearChangedRoles(); 0674 updateDelayModelUpdates(); 0675 } 0676 } 0677 0678 void NetworkModel::accessPointSignalStrengthChanged(int signal) 0679 { 0680 auto apPtr = qobject_cast<NetworkManager::AccessPoint *>(sender()); 0681 if (!apPtr) { 0682 return; 0683 } 0684 0685 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, apPtr->ssid())) { 0686 if (item->specificPath() == apPtr->uni()) { 0687 item->setSignal(signal); 0688 updateItem(item); 0689 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "AccessPoint " << item->name() << ": signal changed to " << item->signal(); 0690 } 0691 } 0692 } 0693 0694 void NetworkModel::activeConnectionAdded(const QString &activeConnection) 0695 { 0696 NetworkManager::ActiveConnection::Ptr activeCon = NetworkManager::findActiveConnection(activeConnection); 0697 0698 if (activeCon) { 0699 addActiveConnection(activeCon); 0700 } 0701 } 0702 0703 void NetworkModel::activeConnectionRemoved(const QString &activeConnection) 0704 { 0705 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::ActiveConnection, activeConnection)) { 0706 item->setActiveConnectionPath(QString()); 0707 item->setConnectionState(NetworkManager::ActiveConnection::Deactivated); 0708 item->setVpnState(NetworkManager::VpnConnection::Disconnected); 0709 updateItem(item); 0710 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": active connection removed"; 0711 } 0712 } 0713 0714 void NetworkModel::activeConnectionStateChanged(NetworkManager::ActiveConnection::State state) 0715 { 0716 auto activePtr = qobject_cast<NetworkManager::ActiveConnection *>(sender()); 0717 0718 if (!activePtr) { 0719 return; 0720 } 0721 0722 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::ActiveConnection, activePtr->path())) { 0723 item->setConnectionState(state); 0724 updateItem(item); 0725 qCDebug(PLASMA_NM_LIBS_LOG) << "Item " << item->name() << ": active connection changed to " << item->connectionState(); 0726 } 0727 } 0728 0729 void NetworkModel::activeVpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason) 0730 { 0731 Q_UNUSED(reason) 0732 auto activePtr = qobject_cast<NetworkManager::ActiveConnection *>(sender()); 0733 0734 if (!activePtr) { 0735 return; 0736 } 0737 0738 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::ActiveConnection, activePtr->path())) { 0739 if (state == NetworkManager::VpnConnection::Prepare // 0740 || state == NetworkManager::VpnConnection::NeedAuth // 0741 || state == NetworkManager::VpnConnection::Connecting // 0742 || state == NetworkManager::VpnConnection::GettingIpConfig) { 0743 item->setConnectionState(NetworkManager::ActiveConnection::Activating); 0744 } else if (state == NetworkManager::VpnConnection::Activated) { 0745 item->setConnectionState(NetworkManager::ActiveConnection::Activated); 0746 } else { 0747 item->setConnectionState(NetworkManager::ActiveConnection::Deactivated); 0748 } 0749 item->setVpnState(state); 0750 updateItem(item); 0751 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": active connection changed to " << item->connectionState(); 0752 } 0753 } 0754 0755 void NetworkModel::availableConnectionAppeared(const QString &connection) 0756 { 0757 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast<NetworkManager::Device *>(sender())->uni()); 0758 if (!device) { 0759 return; 0760 } 0761 0762 addAvailableConnection(connection, device); 0763 } 0764 0765 void NetworkModel::availableConnectionDisappeared(const QString &connection) 0766 { 0767 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { 0768 bool available = false; 0769 const QString devicePath = item->devicePath(); 0770 const QString specificPath = item->specificPath(); 0771 0772 // We have to check whether the connection is still available, because it might be 0773 // presented in the model for more devices and we don't want to remove it for all of them. 0774 0775 // Check whether the device is still available 0776 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(devicePath); 0777 if (device) { 0778 // Check whether the connection is still listed as available 0779 for (const NetworkManager::Connection::Ptr &connection : device->availableConnections()) { 0780 if (connection->path() == item->connectionPath()) { 0781 available = true; 0782 break; 0783 } 0784 } 0785 } 0786 0787 if (!available) { 0788 item->setDeviceName(QString()); 0789 item->setDevicePath(QString()); 0790 item->setDeviceState(NetworkManager::Device::UnknownState); 0791 item->setSignal(0); 0792 item->setSpecificPath(QString()); 0793 qCDebug(PLASMA_NM_LIBS_LOG) << "Item" << item->name() << "removed as available connection"; 0794 // Check whether the connection is still available as an access point, this happens 0795 // when we change its properties, like ssid, bssid, security etc. 0796 if (item->type() == NetworkManager::ConnectionSettings::Wireless && !specificPath.isEmpty()) { 0797 if (device && device->type() == NetworkManager::Device::Wifi) { 0798 NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>(); 0799 if (wifiDevice) { 0800 NetworkManager::AccessPoint::Ptr ap = wifiDevice->findAccessPoint(specificPath); 0801 if (ap) { 0802 NetworkManager::WirelessNetwork::Ptr network = wifiDevice->findNetwork(ap->ssid()); 0803 if (network) { 0804 addWirelessNetwork(network, wifiDevice); 0805 } 0806 } 0807 } 0808 } 0809 } 0810 0811 if (item->duplicate()) { 0812 removeItem(item); 0813 qCDebug(PLASMA_NM_LIBS_LOG) << "Duplicate item" << item->name() << "removed completely"; 0814 } else { 0815 updateItem(item); 0816 } 0817 } 0818 available = false; 0819 } 0820 } 0821 0822 void NetworkModel::connectionAdded(const QString &connection) 0823 { 0824 NetworkManager::Connection::Ptr newConnection = NetworkManager::findConnection(connection); 0825 if (newConnection) { 0826 addConnection(newConnection); 0827 } 0828 } 0829 0830 void NetworkModel::connectionRemoved(const QString &connection) 0831 { 0832 bool remove = false; 0833 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { 0834 // When the item type is wireless, we can remove only the connection and leave it as an available access point 0835 if (item->type() == NetworkManager::ConnectionSettings::Wireless && !item->devicePath().isEmpty()) { 0836 for (NetworkModelItem *secondItem : m_list.items()) { 0837 // Remove it entirely when there is another connection with the same configuration and for the same device 0838 // or it's a shared connection 0839 if ((item->mode() != NetworkManager::WirelessSetting::Infrastructure) 0840 || (item->connectionPath() != secondItem->connectionPath() // 0841 && item->devicePath() == secondItem->devicePath() // 0842 && item->mode() == secondItem->mode() // 0843 && item->securityType() == secondItem->securityType() // 0844 && item->ssid() == secondItem->ssid())) { 0845 remove = true; 0846 break; 0847 } 0848 } 0849 0850 if (!remove) { 0851 item->setConnectionPath(QString()); 0852 item->setName(item->ssid()); 0853 item->setSlave(false); 0854 item->setTimestamp(QDateTime()); 0855 item->setUuid(QString()); 0856 updateItem(item); 0857 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": connection removed"; 0858 } 0859 } else { 0860 remove = true; 0861 } 0862 0863 if (remove) { 0864 removeItem(item); 0865 qCDebug(PLASMA_NM_LIBS_LOG) << "Item" << item->name() << "removed completely"; 0866 } 0867 remove = false; 0868 } 0869 } 0870 0871 void NetworkModel::connectionUpdated() 0872 { 0873 auto connectionPtr = qobject_cast<NetworkManager::Connection *>(sender()); 0874 if (!connectionPtr) { 0875 return; 0876 } 0877 0878 NetworkManager::ConnectionSettings::Ptr settings = connectionPtr->settings(); 0879 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connectionPtr->path())) { 0880 item->setConnectionPath(connectionPtr->path()); 0881 item->setName(settings->id()); 0882 item->setTimestamp(settings->timestamp()); 0883 item->setType(settings->connectionType()); 0884 item->setUuid(settings->uuid()); 0885 0886 if (item->type() == NetworkManager::ConnectionSettings::Wireless) { 0887 NetworkManager::WirelessSetting::Ptr wirelessSetting; 0888 wirelessSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>(); 0889 item->setMode(wirelessSetting->mode()); 0890 item->setSecurityType(NetworkManager::securityTypeFromConnectionSetting(settings)); 0891 item->setSsid(QString::fromUtf8(wirelessSetting->ssid())); 0892 // TODO check whether BSSID has changed and update the wireless info 0893 } 0894 0895 updateItem(item); 0896 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": connection updated"; 0897 } 0898 } 0899 0900 void NetworkModel::deviceAdded(const QString &device) 0901 { 0902 NetworkManager::Device::Ptr dev = NetworkManager::findNetworkInterface(device); 0903 if (dev) { 0904 addDevice(dev); 0905 } 0906 } 0907 0908 void NetworkModel::deviceRemoved(const QString &device) 0909 { 0910 // Make all items unavailable 0911 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device)) { 0912 availableConnectionDisappeared(item->connectionPath()); 0913 } 0914 } 0915 0916 void NetworkModel::deviceStateChanged(NetworkManager::Device::State state, 0917 NetworkManager::Device::State oldState, 0918 NetworkManager::Device::StateChangeReason reason) 0919 { 0920 Q_UNUSED(oldState); 0921 Q_UNUSED(reason); 0922 0923 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast<NetworkManager::Device *>(sender())->uni()); 0924 0925 if (!device) { 0926 return; 0927 } 0928 0929 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { 0930 item->setDeviceState(state); 0931 updateItem(item); 0932 // qCDebug(PLASMA_NM_LIBS_LOG) << "Item " << item->name() << ": device state changed to " << item->deviceState(); 0933 } 0934 } 0935 0936 void NetworkModel::gsmNetworkAccessTechnologiesChanged(QFlags<MMModemAccessTechnology> accessTechnologies) 0937 { 0938 Q_UNUSED(accessTechnologies); 0939 auto gsmNetwork = qobject_cast<ModemManager::Modem *>(sender()); 0940 if (!gsmNetwork) 0941 return; 0942 0943 for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { 0944 if (dev->type() != NetworkManager::Device::Modem) { 0945 continue; 0946 } 0947 0948 ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(dev->udi()); 0949 if (!modem) { 0950 continue; 0951 } 0952 0953 if (!modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { 0954 continue; 0955 } 0956 0957 ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>(); 0958 if (!modemNetwork || modemNetwork->device() != gsmNetwork->device()) { 0959 continue; 0960 } 0961 0962 // TODO store access technology internally? 0963 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, dev->uni())) { 0964 updateItem(item); 0965 } 0966 } 0967 } 0968 0969 void NetworkModel::gsmNetworkCurrentModesChanged() 0970 { 0971 auto gsmNetwork = qobject_cast<ModemManager::Modem *>(sender()); 0972 if (!gsmNetwork) { 0973 return; 0974 } 0975 0976 for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { 0977 if (dev->type() != NetworkManager::Device::Modem) 0978 continue; 0979 0980 ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(dev->udi()); 0981 if (!modem) { 0982 continue; 0983 } 0984 0985 if (!modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { 0986 continue; 0987 } 0988 0989 ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>(); 0990 if (!modemNetwork || modemNetwork->device() != gsmNetwork->device()) { 0991 continue; 0992 } 0993 0994 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, dev->uni())) { 0995 updateItem(item); 0996 } 0997 } 0998 } 0999 1000 void NetworkModel::gsmNetworkSignalQualityChanged(const ModemManager::SignalQualityPair &signalQuality) 1001 { 1002 auto gsmNetwork = qobject_cast<ModemManager::Modem *>(sender()); 1003 if (!gsmNetwork) { 1004 return; 1005 } 1006 1007 for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { 1008 if (dev->type() != NetworkManager::Device::Modem) { 1009 continue; 1010 } 1011 1012 ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(dev->udi()); 1013 if (!modem) { 1014 continue; 1015 } 1016 1017 if (!modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { 1018 continue; 1019 } 1020 1021 ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>(); 1022 if (!modemNetwork || modemNetwork->device() != gsmNetwork->device()) { 1023 continue; 1024 } 1025 1026 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, dev->uni())) { 1027 item->setSignal(signalQuality.signal); 1028 updateItem(item); 1029 } 1030 } 1031 } 1032 1033 void NetworkModel::ipConfigChanged() 1034 { 1035 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast<NetworkManager::Device *>(sender())->uni()); 1036 1037 if (!device) { 1038 return; 1039 } 1040 1041 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { 1042 updateItem(item); 1043 // qCDebug(PLASMA_NM_LIBS_LOG) << "Item " << item->name() << ": device ipconfig changed"; 1044 } 1045 } 1046 1047 void NetworkModel::ipInterfaceChanged() 1048 { 1049 auto device = qobject_cast<NetworkManager::Device *>(sender()); 1050 if (!device) { 1051 return; 1052 } 1053 1054 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { 1055 if (device->ipInterfaceName().isEmpty()) { 1056 item->setDeviceName(device->interfaceName()); 1057 } else { 1058 item->setDeviceName(device->ipInterfaceName()); 1059 } 1060 } 1061 } 1062 1063 void NetworkModel::statusChanged(NetworkManager::Status status) 1064 { 1065 Q_UNUSED(status); 1066 1067 qCDebug(PLASMA_NM_LIBS_LOG) << "NetworkManager state changed to" << status; 1068 // This has probably effect only for VPN connections 1069 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Type, NetworkManager::ConnectionSettings::Vpn)) { 1070 updateItem(item); 1071 } 1072 } 1073 1074 void NetworkModel::wirelessNetworkAppeared(const QString &ssid) 1075 { 1076 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast<NetworkManager::Device *>(sender())->uni()); 1077 if (device && device->type() == NetworkManager::Device::Wifi) { 1078 NetworkManager::WirelessDevice::Ptr wirelessDevice = device.objectCast<NetworkManager::WirelessDevice>(); 1079 NetworkManager::WirelessNetwork::Ptr network = wirelessDevice->findNetwork(ssid); 1080 addWirelessNetwork(network, wirelessDevice); 1081 } 1082 } 1083 1084 void NetworkModel::wirelessNetworkDisappeared(const QString &ssid) 1085 { 1086 NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast<NetworkManager::Device *>(sender())->uni()); 1087 if (!device) { 1088 return; 1089 } 1090 1091 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, ssid, device->uni())) { 1092 // Remove the entire item, because it's only AP or it's a duplicated available connection 1093 if (item->itemType() == NetworkModelItem::AvailableAccessPoint || item->duplicate()) { 1094 removeItem(item); 1095 qCDebug(PLASMA_NM_LIBS_LOG) << "Wireless network" << item->name() << "removed completely"; 1096 // Remove only AP and device from the item and leave it as an unavailable connection 1097 } else { 1098 if (item->mode() == NetworkManager::WirelessSetting::Infrastructure) { 1099 item->setDeviceName(QString()); 1100 item->setDevicePath(QString()); 1101 item->setSpecificPath(QString()); 1102 } 1103 item->setSignal(0); 1104 updateItem(item); 1105 qCDebug(PLASMA_NM_LIBS_LOG).nospace() << "Item " << item->name() << ": wireless network removed"; 1106 } 1107 } 1108 } 1109 1110 void NetworkModel::wirelessNetworkReferenceApChanged(const QString &accessPoint) 1111 { 1112 auto networkPtr = qobject_cast<NetworkManager::WirelessNetwork *>(sender()); 1113 1114 if (!networkPtr) { 1115 return; 1116 } 1117 1118 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, networkPtr->ssid(), networkPtr->device())) { 1119 NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(item->connectionPath()); 1120 if (!connection) { 1121 continue; 1122 } 1123 1124 NetworkManager::WirelessSetting::Ptr wirelessSetting = 1125 connection->settings()->setting(NetworkManager::Setting::Wireless).staticCast<NetworkManager::WirelessSetting>(); 1126 if (!wirelessSetting) { 1127 continue; 1128 } 1129 1130 if (wirelessSetting->bssid().isEmpty()) { 1131 item->setSpecificPath(accessPoint); 1132 updateItem(item); 1133 } 1134 } 1135 } 1136 1137 void NetworkModel::wirelessNetworkSignalChanged(int signal) 1138 { 1139 auto networkPtr = qobject_cast<NetworkManager::WirelessNetwork *>(sender()); 1140 if (!networkPtr) { 1141 return; 1142 } 1143 1144 for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, networkPtr->ssid(), networkPtr->device())) { 1145 if (item->specificPath() == networkPtr->referenceAccessPoint()->uni()) { 1146 item->setSignal(signal); 1147 updateItem(item); 1148 // qCDebug(PLASMA_NM_LIBS_LOG) << "Wireless network " << item->name() << ": signal changed to " << item->signal(); 1149 } 1150 } 1151 } 1152 1153 NetworkManager::WirelessSecurityType NetworkModel::alternativeWirelessSecurity(const NetworkManager::WirelessSecurityType type) 1154 { 1155 if (type == NetworkManager::WpaPsk) { 1156 return NetworkManager::Wpa2Psk; 1157 } else if (type == NetworkManager::WpaEap) { 1158 return NetworkManager::Wpa2Eap; 1159 } else if (type == NetworkManager::Wpa2Psk) { 1160 return NetworkManager::WpaPsk; 1161 } else if (type == NetworkManager::Wpa2Eap) { 1162 return NetworkManager::WpaEap; 1163 } 1164 return type; 1165 } 1166 1167 void NetworkModel::updateFromWirelessNetwork(NetworkModelItem *item, 1168 const NetworkManager::WirelessNetwork::Ptr &network, 1169 const NetworkManager::WirelessDevice::Ptr &device) 1170 { 1171 NetworkManager::WirelessSecurityType securityType = NetworkManager::UnknownSecurity; 1172 NetworkManager::AccessPoint::Ptr ap = network->referenceAccessPoint(); 1173 if (ap && ap->capabilities().testFlag(NetworkManager::AccessPoint::Privacy)) { 1174 securityType = NetworkManager::findBestWirelessSecurity(device->wirelessCapabilities(), 1175 true, 1176 (device->mode() == NetworkManager::WirelessDevice::Adhoc), 1177 ap->capabilities(), 1178 ap->wpaFlags(), 1179 ap->rsnFlags()); 1180 } 1181 1182 // Check whether the connection is associated with some concrete AP 1183 NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(item->connectionPath()); 1184 if (connection) { 1185 NetworkManager::WirelessSetting::Ptr wirelessSetting = 1186 connection->settings()->setting(NetworkManager::Setting::Wireless).staticCast<NetworkManager::WirelessSetting>(); 1187 if (wirelessSetting) { 1188 if (!wirelessSetting->bssid().isEmpty()) { 1189 for (const NetworkManager::AccessPoint::Ptr &ap : network->accessPoints()) { 1190 if (ap->hardwareAddress() == NetworkManager::macAddressAsString(wirelessSetting->bssid())) { 1191 item->setSignal(ap->signalStrength()); 1192 item->setSpecificPath(ap->uni()); 1193 // We need to watch this AP for signal changes 1194 connect(ap.data(), 1195 &NetworkManager::AccessPoint::signalStrengthChanged, 1196 this, 1197 &NetworkModel::accessPointSignalStrengthChanged, 1198 Qt::UniqueConnection); 1199 } 1200 } 1201 } else { 1202 item->setSignal(network->signalStrength()); 1203 item->setSpecificPath(network->referenceAccessPoint()->uni()); 1204 } 1205 } 1206 } 1207 item->setSecurityType(securityType); 1208 updateItem(item); 1209 }