File indexing completed on 2024-04-28 15:33:08
0001 /* 0002 SPDX-FileCopyrightText: 2014 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 "fakenetwork.h" 0008 #include "connection.h" 0009 #include "wireddevice.h" 0010 #include "wirelessdevice.h" 0011 0012 #include <QDBusConnection> 0013 #include <QDBusMetaType> 0014 #include <QTimer> 0015 0016 #include "../manager.h" 0017 #include "connectionsettings.h" 0018 0019 FakeNetwork::FakeNetwork(QObject *parent) 0020 : QObject(parent) 0021 , m_activatingConnection(QDBusObjectPath("/")) 0022 , m_connectivity(NetworkManager::Connectivity::NoConnectivity) 0023 , m_networkingEnabled(true) 0024 , m_primaryConnection(QDBusObjectPath("/")) 0025 , m_state(20) 0026 , m_version(QLatin1String("0.9.10.0")) 0027 , m_wimaxEnabled(true) 0028 , m_wimaxHardwareEnabled(true) 0029 , m_wirelessEnabled(true) 0030 , m_wirelessHardwareEnabled(true) 0031 , m_wwanEnabled(true) 0032 , m_wwanHardwareEnabled(true) 0033 , m_activeConnectionsCounter(0) 0034 , m_deviceCounter(0) 0035 , m_settings(new Settings(this)) 0036 { 0037 qDBusRegisterMetaType<QDBusObjectPath>(); 0038 registerService(); 0039 connect(m_settings, &Settings::connectionAdded, this, &FakeNetwork::onConnectionAdded); 0040 connect(m_settings, &Settings::connectionRemoved, this, &FakeNetwork::onConnectionRemoved); 0041 } 0042 0043 FakeNetwork::~FakeNetwork() 0044 { 0045 unregisterService(); 0046 qDeleteAll(m_devices); 0047 delete m_settings; 0048 } 0049 0050 QDBusObjectPath FakeNetwork::activatingConnection() const 0051 { 0052 return m_activatingConnection; 0053 } 0054 0055 QList<QDBusObjectPath> FakeNetwork::activeConnections() const 0056 { 0057 return m_activeConnections.keys(); 0058 } 0059 0060 uint FakeNetwork::connectivity() const 0061 { 0062 return m_connectivity; 0063 } 0064 0065 QList<QDBusObjectPath> FakeNetwork::devices() const 0066 { 0067 return m_devices.keys(); 0068 } 0069 0070 bool FakeNetwork::networkingEnabled() const 0071 { 0072 return m_networkingEnabled; 0073 } 0074 0075 QDBusObjectPath FakeNetwork::primaryConnection() const 0076 { 0077 return m_primaryConnection; 0078 } 0079 0080 uint FakeNetwork::state() const 0081 { 0082 return m_state; 0083 } 0084 0085 QString FakeNetwork::version() const 0086 { 0087 return m_version; 0088 } 0089 0090 bool FakeNetwork::wimaxEnabled() const 0091 { 0092 return m_wimaxEnabled; 0093 } 0094 0095 void FakeNetwork::setWimaxEnabled(bool enabled) 0096 { 0097 m_wimaxEnabled = enabled; 0098 0099 QVariantMap map; 0100 map.insert(QLatin1String("WimaxEnabled"), m_wimaxEnabled); 0101 Q_EMIT PropertiesChanged(map); 0102 } 0103 0104 bool FakeNetwork::wimaxHardwareEnabled() const 0105 { 0106 return m_wimaxHardwareEnabled; 0107 } 0108 0109 void FakeNetwork::setWimaxHardwareEnabled(bool enabled) 0110 { 0111 m_wimaxHardwareEnabled = enabled; 0112 0113 QVariantMap map; 0114 map.insert(QLatin1String("WimaxHardwareEnabled"), m_wimaxHardwareEnabled); 0115 Q_EMIT PropertiesChanged(map); 0116 } 0117 0118 bool FakeNetwork::wirelessEnabled() const 0119 { 0120 return m_wirelessEnabled; 0121 } 0122 0123 void FakeNetwork::setWirelessEnabled(bool enabled) 0124 { 0125 m_wirelessEnabled = enabled; 0126 0127 QVariantMap map; 0128 map.insert(QLatin1String("WirelessEnabled"), m_wirelessEnabled); 0129 Q_EMIT PropertiesChanged(map); 0130 } 0131 0132 bool FakeNetwork::wirelessHardwareEnabled() const 0133 { 0134 return m_wirelessHardwareEnabled; 0135 } 0136 0137 void FakeNetwork::setWirelessHardwareEnabled(bool enabled) 0138 { 0139 m_wirelessHardwareEnabled = enabled; 0140 0141 QVariantMap map; 0142 map.insert(QLatin1String("WirelessHardwareEnabled"), m_wirelessHardwareEnabled); 0143 Q_EMIT PropertiesChanged(map); 0144 } 0145 0146 bool FakeNetwork::wwanEnabled() const 0147 { 0148 return m_wwanEnabled; 0149 } 0150 0151 void FakeNetwork::setWwanEnabled(bool enabled) 0152 { 0153 m_wwanEnabled = enabled; 0154 0155 QVariantMap map; 0156 map.insert(QLatin1String("WwanEnabled"), m_wwanEnabled); 0157 Q_EMIT PropertiesChanged(map); 0158 } 0159 0160 bool FakeNetwork::wwanHardwareEnabled() const 0161 { 0162 return m_wwanHardwareEnabled; 0163 } 0164 0165 void FakeNetwork::addDevice(Device *device) 0166 { 0167 QString newDevicePath = QString("/org/kde/fakenetwork/Devices/") + QString::number(m_deviceCounter++); 0168 device->setDevicePath(newDevicePath); 0169 m_devices.insert(QDBusObjectPath(newDevicePath), device); 0170 QDBusConnection::sessionBus().registerObject(newDevicePath, device, QDBusConnection::ExportScriptableContents); 0171 Q_EMIT DeviceAdded(QDBusObjectPath(newDevicePath)); 0172 } 0173 0174 void FakeNetwork::removeDevice(Device *device) 0175 { 0176 m_devices.remove(QDBusObjectPath(device->devicePath())); 0177 QDBusConnection::sessionBus().unregisterObject(device->devicePath()); 0178 Q_EMIT DeviceRemoved(QDBusObjectPath(device->devicePath())); 0179 } 0180 0181 void FakeNetwork::registerService() 0182 { 0183 QDBusConnection::sessionBus().registerService(QLatin1String("org.kde.fakenetwork")); 0184 QDBusConnection::sessionBus().registerObject(QLatin1String("/org/kde/fakenetwork"), this, QDBusConnection::ExportScriptableContents); 0185 QDBusConnection::sessionBus().registerObject(QLatin1String("/org/kde/fakenetwork/Settings"), m_settings, QDBusConnection::ExportScriptableContents); 0186 0187 for (auto it = m_devices.cbegin(); it != m_devices.cend(); ++it) { 0188 const QDBusObjectPath &devicePath = it.key(); 0189 QDBusConnection::sessionBus().registerObject(devicePath.path(), it.value(), QDBusConnection::ExportScriptableContents); 0190 Q_EMIT DeviceAdded(devicePath); 0191 } 0192 } 0193 0194 void FakeNetwork::unregisterService() 0195 { 0196 for (auto it = m_devices.cbegin(); it != m_devices.cend(); ++it) { 0197 const QDBusObjectPath &devicePath = it.key(); 0198 QDBusConnection::sessionBus().unregisterObject(devicePath.path()); 0199 Q_EMIT DeviceRemoved(devicePath); 0200 } 0201 0202 QDBusConnection::sessionBus().unregisterObject(QLatin1String("/org/kde/fakenetwork/Settings")); 0203 QDBusConnection::sessionBus().unregisterObject(QLatin1String("/org/kde/fakenetwork")); 0204 QDBusConnection::sessionBus().unregisterService(QLatin1String("org.kde.fakenetwork")); 0205 } 0206 0207 QDBusObjectPath FakeNetwork::ActivateConnection(const QDBusObjectPath &connection, const QDBusObjectPath &device, const QDBusObjectPath &specific_object) 0208 { 0209 QString newActiveConnectionPath = QString("/org/kde/fakenetwork/ActiveConnection/") + QString::number(m_activeConnectionsCounter++); 0210 ActiveConnection *newActiveConnection = new ActiveConnection(this); 0211 newActiveConnection->addDevice(device); 0212 newActiveConnection->setActiveConnectionPath(newActiveConnectionPath); 0213 newActiveConnection->setConnection(connection); 0214 newActiveConnection->setSpecificObject(specific_object); 0215 newActiveConnection->setState(NetworkManager::ActiveConnection::Activating); 0216 0217 m_activeConnections.insert(QDBusObjectPath(newActiveConnectionPath), newActiveConnection); 0218 QDBusConnection::sessionBus().registerObject(newActiveConnectionPath, newActiveConnection, QDBusConnection::ExportScriptableContents); 0219 0220 m_activatingConnection = QDBusObjectPath(newActiveConnectionPath); 0221 0222 QVariantMap map; 0223 map.insert(QLatin1String("ActiveConnections"), QVariant::fromValue<QList<QDBusObjectPath>>(m_activeConnections.keys())); 0224 map.insert(QLatin1String("ActivatingConnection"), QVariant::fromValue(QDBusObjectPath(newActiveConnectionPath))); 0225 Q_EMIT PropertiesChanged(map); 0226 0227 Device *usedDevice = static_cast<Device *>(QDBusConnection::sessionBus().objectRegisteredAt(device.path())); 0228 if (usedDevice) { 0229 m_activatedDevice = usedDevice->devicePath(); 0230 // Start simulation of activation 0231 usedDevice->setActiveConnection(newActiveConnectionPath); 0232 usedDevice->setState(NetworkManager::Device::Preparing); 0233 QTimer::singleShot(100, this, SLOT(updateConnectingState())); 0234 } 0235 0236 return QDBusObjectPath(newActiveConnectionPath); 0237 } 0238 0239 void FakeNetwork::updateConnectingState() 0240 { 0241 QVariantMap deviceMap; 0242 Device *device = m_devices.value(QDBusObjectPath(m_activatedDevice)); 0243 if (device->state() == NetworkManager::Device::Preparing) { 0244 device->setState(NetworkManager::Device::ConfiguringHardware); 0245 } else if (device->state() == NetworkManager::Device::ConfiguringHardware) { 0246 device->setState(NetworkManager::Device::NeedAuth); 0247 } else if (device->state() == NetworkManager::Device::NeedAuth) { 0248 device->setState(NetworkManager::Device::ConfiguringIp); 0249 } else if (device->state() == NetworkManager::Device::ConfiguringIp) { 0250 device->setState(NetworkManager::Device::CheckingIp); 0251 } else if (device->state() == NetworkManager::Device::CheckingIp) { 0252 device->setState(NetworkManager::Device::Activated); 0253 0254 ActiveConnection *activeConnection = 0255 static_cast<ActiveConnection *>(QDBusConnection::sessionBus().objectRegisteredAt(device->activeConnection().path())); 0256 if (activeConnection) { 0257 QVariantMap activeConnectionMap; 0258 activeConnectionMap.insert(QLatin1String("State"), NetworkManager::ActiveConnection::Activated); 0259 0260 activeConnection->setState(NetworkManager::ActiveConnection::Activated); 0261 QDBusMessage message = QDBusMessage::createSignal(activeConnection->activeConnectionPath(), 0262 QLatin1String("org.kde.fakenetwork.Connection.Active"), 0263 QLatin1String("PropertiesChanged")); 0264 message << activeConnectionMap; 0265 QDBusConnection::sessionBus().send(message); 0266 0267 QDBusMessage message2 = QDBusMessage::createSignal(activeConnection->activeConnectionPath(), 0268 QLatin1String("org.kde.fakenetwork.Connection.Active"), 0269 QLatin1String("StateChanged")); 0270 message2 << (uint)2 << (uint)1; // NM_ACTIVE_CONNECTION_STATE_ACTIVATED << NM_ACTIVE_CONNECTION_STATE_REASON_NONE 0271 QDBusConnection::sessionBus().send(message2); 0272 } 0273 // TODO: set dhcp4Config, dhcp6Config, ip4Config, ip6Config 0274 // IP Interface is usually same as interface 0275 device->setIpInterface(device->interface()); 0276 // Set some IP address 0277 device->setIpv4Address(1763189258); 0278 0279 deviceMap.insert(QLatin1String("IpInterface"), device->ipInterface()); 0280 deviceMap.insert(QLatin1String("Ip4Address"), device->ip4Address()); 0281 deviceMap.insert(QLatin1String("ActiveConnection"), m_activatingConnection.path()); 0282 0283 // Update FakeNetwork state, connectivity, primary connection 0284 m_connectivity = NetworkManager::Connectivity::Full; 0285 m_primaryConnection = m_activatingConnection; 0286 m_activatingConnection = QDBusObjectPath("/"); 0287 m_state = 70; 0288 QVariantMap networkMap; 0289 networkMap.insert(QLatin1String("ActivatingConnection"), QVariant::fromValue(m_activatingConnection)); 0290 networkMap.insert(QLatin1String("Connectivity"), NetworkManager::Connectivity::Full); 0291 networkMap.insert(QLatin1String("PrimaryConnection"), QVariant::fromValue(m_primaryConnection)); 0292 networkMap.insert(QLatin1String("State"), m_state); 0293 0294 QDBusMessage message = 0295 QDBusMessage::createSignal(QLatin1String("/org/kde/fakenetwork"), QLatin1String("org.kde.fakenetwork"), QLatin1String("PropertiesChanged")); 0296 message << networkMap; 0297 QDBusConnection::sessionBus().send(message); 0298 0299 Q_EMIT StateChanged(m_state); 0300 } 0301 0302 deviceMap.insert(QLatin1String("State"), device->state()); 0303 QDBusMessage message = QDBusMessage::createSignal(device->devicePath(), device->deviceInterface(), QLatin1String("PropertiesChanged")); 0304 message << deviceMap; 0305 QDBusConnection::sessionBus().send(message); 0306 0307 if (device->state() != NetworkManager::Device::Activated) { 0308 QTimer::singleShot(100, this, SLOT(updateConnectingState())); 0309 } 0310 } 0311 0312 uint FakeNetwork::CheckConnectivity() const 0313 { 0314 return m_connectivity; 0315 } 0316 0317 void FakeNetwork::DeactivateConnection(const QDBusObjectPath &active_connection) 0318 { 0319 ActiveConnection *activeConnection = m_activeConnections.value(active_connection); 0320 if (activeConnection) { 0321 activeConnection->setState(NetworkManager::ActiveConnection::Deactivating); 0322 0323 QVariantMap activeConnectionMap; 0324 activeConnectionMap.insert(QLatin1String("State"), NetworkManager::ActiveConnection::Deactivating); 0325 0326 activeConnection->setState(NetworkManager::ActiveConnection::Activated); 0327 QDBusMessage message = QDBusMessage::createSignal(activeConnection->activeConnectionPath(), 0328 QLatin1String("org.kde.fakenetwork.Connection.Active"), 0329 QLatin1String("PropertiesChanged")); 0330 message << activeConnectionMap; 0331 QDBusConnection::sessionBus().send(message); 0332 0333 QDBusMessage message2 = QDBusMessage::createSignal(activeConnection->activeConnectionPath(), 0334 QLatin1String("org.kde.fakenetwork.Connection.Active"), 0335 QLatin1String("StateChanged")); 0336 message2 << (uint)4 << (uint)2; // NM_ACTIVE_CONNECTION_STATE_DEACTIVATED << NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED 0337 QDBusConnection::sessionBus().send(message2); 0338 0339 Device *device = m_devices.value(activeConnection->devices().first()); 0340 if (device) { 0341 m_deactivatedDevice = device->devicePath(); 0342 device->setState(NetworkManager::Device::Deactivating); 0343 QTimer::singleShot(100, this, SLOT(updateDeactivatingState())); 0344 } 0345 0346 // Update FakeNetwork state, connectivity, primary connection 0347 m_connectivity = NetworkManager::Connectivity::NoConnectivity; 0348 m_primaryConnection = QDBusObjectPath("/"); 0349 m_state = 20; 0350 QVariantMap networkMap; 0351 networkMap.insert(QLatin1String("Connectivity"), m_connectivity); 0352 networkMap.insert(QLatin1String("PrimaryConnection"), QVariant::fromValue(m_primaryConnection)); 0353 networkMap.insert(QLatin1String("State"), m_state); 0354 0355 message = QDBusMessage::createSignal(QLatin1String("/org/kde/fakenetwork"), QLatin1String("org.kde.fakenetwork"), QLatin1String("PropertiesChanged")); 0356 message << networkMap; 0357 QDBusConnection::sessionBus().send(message); 0358 0359 Q_EMIT StateChanged(m_state); 0360 } 0361 } 0362 0363 void FakeNetwork::updateDeactivatingState() 0364 { 0365 QVariantMap deviceMap; 0366 Device *device = m_devices.value(QDBusObjectPath(m_deactivatedDevice)); 0367 ActiveConnection *activeConnection = static_cast<ActiveConnection *>(QDBusConnection::sessionBus().objectRegisteredAt(device->activeConnection().path())); 0368 if (activeConnection) { 0369 QVariantMap activeConnectionMap; 0370 activeConnectionMap.insert(QLatin1String("State"), NetworkManager::ActiveConnection::Deactivated); 0371 0372 activeConnection->setState(NetworkManager::ActiveConnection::Activated); 0373 QDBusMessage message = QDBusMessage::createSignal(activeConnection->activeConnectionPath(), 0374 QLatin1String("org.kde.fakenetwork.Connection.Active"), 0375 QLatin1String("PropertiesChanged")); 0376 message << activeConnectionMap; 0377 QDBusConnection::sessionBus().send(message); 0378 0379 QDBusMessage message2 = QDBusMessage::createSignal(activeConnection->activeConnectionPath(), 0380 QLatin1String("org.kde.fakenetwork.Connection.Active"), 0381 QLatin1String("StateChanged")); 0382 message2 << (uint)3 << (uint)2; // NM_ACTIVE_CONNECTION_STATE_DEACTIVATING << NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED 0383 QDBusConnection::sessionBus().send(message2); 0384 0385 removeActiveConnection(QDBusObjectPath(activeConnection->activeConnectionPath())); 0386 } 0387 0388 device->setActiveConnection(QLatin1String("/")); 0389 device->setState(NetworkManager::Device::Disconnected); 0390 // TODO: set dhcp4Config, dhcp6Config, ip4Config, ip6Config 0391 // IP Interface is usually same as interface 0392 device->setIpInterface(""); 0393 // Set some IP address 0394 device->setIpv4Address(0); 0395 0396 deviceMap.insert(QLatin1String("ActiveConnection"), device->activeConnection().path()); 0397 deviceMap.insert(QLatin1String("IpInterface"), device->ipInterface()); 0398 deviceMap.insert(QLatin1String("Ip4Address"), device->ip4Address()); 0399 deviceMap.insert(QLatin1String("State"), device->state()); 0400 0401 QDBusMessage message = QDBusMessage::createSignal(device->devicePath(), device->deviceInterface(), QLatin1String("PropertiesChanged")); 0402 message << deviceMap; 0403 QDBusConnection::sessionBus().send(message); 0404 } 0405 0406 QDBusObjectPath FakeNetwork::GetDeviceByIpIface(const QString &iface) 0407 { 0408 Q_UNUSED(iface) 0409 // TODO 0410 return QDBusObjectPath(); 0411 } 0412 0413 QList<QDBusObjectPath> FakeNetwork::GetDevices() const 0414 { 0415 return m_devices.keys(); 0416 } 0417 0418 void FakeNetwork::onConnectionAdded(const QDBusObjectPath &connection) 0419 { 0420 Connection *newConnection = static_cast<Connection *>(QDBusConnection::sessionBus().objectRegisteredAt(connection.path())); 0421 if (newConnection) { 0422 NMVariantMapMap settings = newConnection->GetSettings(); 0423 NetworkManager::ConnectionSettings::ConnectionType type = 0424 NetworkManager::ConnectionSettings::typeFromString(settings.value(QLatin1String("connection")).value(QLatin1String("type")).toString()); 0425 if (!m_devices.isEmpty()) { 0426 Device *selectedDevice = nullptr; 0427 for (Device *device : std::as_const(m_devices)) { 0428 if (type == NetworkManager::ConnectionSettings::Wired && device->deviceType() == NetworkManager::Device::Ethernet) { 0429 selectedDevice = device; 0430 device->addAvailableConnection(connection); 0431 break; 0432 } else if (type == NetworkManager::ConnectionSettings::Wireless && device->deviceType() == NetworkManager::Device::Wifi) { 0433 selectedDevice = device; 0434 // TODO 0435 break; 0436 } 0437 } 0438 0439 if (selectedDevice) { 0440 QVariantMap map; 0441 map.insert(QLatin1String("AvailableConnections"), QVariant::fromValue<QList<QDBusObjectPath>>(selectedDevice->availableConnections())); 0442 0443 QDBusMessage message = 0444 QDBusMessage::createSignal(selectedDevice->devicePath(), selectedDevice->deviceInterface(), QLatin1String("PropertiesChanged")); 0445 message << map; 0446 QDBusConnection::sessionBus().send(message); 0447 } 0448 } 0449 } 0450 } 0451 0452 void FakeNetwork::onConnectionRemoved(const QDBusObjectPath &connection) 0453 { 0454 for (Device *device : std::as_const(m_devices)) { 0455 if (device && device->availableConnections().contains(connection)) { 0456 device->removeAvailableConnection(connection); 0457 0458 QVariantMap map; 0459 map.insert(QLatin1String("AvailableConnections"), QVariant::fromValue<QList<QDBusObjectPath>>(device->availableConnections())); 0460 0461 QDBusMessage message = QDBusMessage::createSignal(device->devicePath(), device->deviceInterface(), QLatin1String("PropertiesChanged")); 0462 message << map; 0463 QDBusConnection::sessionBus().send(message); 0464 } 0465 } 0466 } 0467 0468 void FakeNetwork::removeActiveConnection(const QDBusObjectPath &activeConnection) 0469 { 0470 delete m_activeConnections.value(activeConnection); 0471 m_activeConnections.remove(activeConnection); 0472 QDBusConnection::sessionBus().unregisterObject(activeConnection.path()); 0473 0474 QVariantMap map; 0475 map.insert(QLatin1String("ActiveConnections"), QVariant::fromValue<QList<QDBusObjectPath>>(m_activeConnections.keys())); 0476 Q_EMIT PropertiesChanged(map); 0477 } 0478 0479 #include "moc_fakenetwork.cpp"