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