diff --git a/debian/control b/debian/control index 751502ff..c5bbf4dd 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 9.0.0), dh-systemd, dpkg-dev (>= 1.16.1~), libnymea-mqtt-dev (>= 0.1.2), - libnymea-networkmanager-dev (>= 0.3.0), + libnymea-networkmanager-dev (>= 0.4.0), libnymea-remoteproxyclient-dev, libqt5websockets5-dev, libqt5bluetooth5, diff --git a/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp b/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp index f6ab3c62..3bf4852c 100644 --- a/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp +++ b/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp @@ -569,7 +569,7 @@ void JsonRPCServerImplementation::setup() registerHandler(new LoggingHandler(this)); registerHandler(new StateHandler(this)); registerHandler(new ConfigurationHandler(this)); - registerHandler(new NetworkManagerHandler(this)); + registerHandler(new NetworkManagerHandler(NymeaCore::instance()->networkManager(), this)); registerHandler(new TagsHandler(this)); registerHandler(new SystemHandler(NymeaCore::instance()->platform(), this)); registerHandler(new UsersHandler(NymeaCore::instance()->userManager(), this)); diff --git a/libnymea-core/jsonrpc/networkmanagerhandler.cpp b/libnymea-core/jsonrpc/networkmanagerhandler.cpp index 41c39679..762c1ade 100644 --- a/libnymea-core/jsonrpc/networkmanagerhandler.cpp +++ b/libnymea-core/jsonrpc/networkmanagerhandler.cpp @@ -76,22 +76,21 @@ The \a params contains the map for the notification. */ - -#include "nymeacore.h" #include "loggingcategories.h" #include "networkmanagerhandler.h" - namespace nymeaserver { /*! Constructs a new \l{NetworkManagerHandler} with the given \a parent. */ -NetworkManagerHandler::NetworkManagerHandler(QObject *parent) : - JsonHandler(parent) +NetworkManagerHandler::NetworkManagerHandler(NetworkManager *networkManager, QObject *parent) : + JsonHandler(parent), + m_networkManager(networkManager) { // Enums registerEnum(); registerEnum(); registerEnum(); + registerEnum(); // Objects QVariantMap wirelessAccessPoint; @@ -106,17 +105,22 @@ NetworkManagerHandler::NetworkManagerHandler(QObject *parent) : QVariantMap wiredNetworkDevice; wiredNetworkDevice.insert("r:interface", enumValueName(String)); wiredNetworkDevice.insert("r:macAddress", enumValueName(String)); + wiredNetworkDevice.insert("r:ipv4Addresses", enumValueName(StringList)); + wiredNetworkDevice.insert("r:ipv6Addresses", enumValueName(StringList)); wiredNetworkDevice.insert("r:state", enumRef()); wiredNetworkDevice.insert("r:bitRate", enumValueName(String)); wiredNetworkDevice.insert("r:pluggedIn", enumValueName(Bool)); registerObject("WiredNetworkDevice", wiredNetworkDevice); QVariantMap wirelessNetworkDevice; - wirelessNetworkDevice.insert("interface", enumValueName(String)); - wirelessNetworkDevice.insert("macAddress", enumValueName(String)); - wirelessNetworkDevice.insert("state", enumRef()); - wirelessNetworkDevice.insert("bitRate", enumValueName(String)); - wirelessNetworkDevice.insert("o:currentAccessPoint", objectRef()); + wirelessNetworkDevice.insert("r:interface", enumValueName(String)); + wirelessNetworkDevice.insert("r:macAddress", enumValueName(String)); + wirelessNetworkDevice.insert("r:ipv4Addresses", enumValueName(StringList)); + wirelessNetworkDevice.insert("r:ipv6Addresses", enumValueName(StringList)); + wirelessNetworkDevice.insert("r:state", enumRef()); + wirelessNetworkDevice.insert("r:bitRate", enumValueName(String)); + wirelessNetworkDevice.insert("r:mode", enumRef()); + wirelessNetworkDevice.insert("r:o:currentAccessPoint", objectRef()); registerObject("WirelessNetworkDevice", wirelessNetworkDevice); // Methods @@ -176,6 +180,15 @@ NetworkManagerHandler::NetworkManagerHandler(QObject *parent) : returns.insert("networkManagerError", enumRef()); registerMethod("ConnectWifiNetwork", description, params, returns); + params.clear(); returns.clear(); + description = "Start a WiFi Access point on the given interface with the given SSID and " + "password. Use DisconnectInterface to stop it again."; + params.insert("interface", enumValueName(String)); + params.insert("ssid", enumValueName(String)); + params.insert("password", enumValueName(String)); + returns.insert("networkManagerError", enumRef()); + registerMethod("StartAccessPoint", description, params, returns); + // Notifications params.clear(); returns.clear(); description = "Emitted whenever a status of a NetworkManager changes."; @@ -212,17 +225,17 @@ NetworkManagerHandler::NetworkManagerHandler(QObject *parent) : params.insert("wiredNetworkDevice", objectRef("WiredNetworkDevice")); registerNotification("WiredNetworkDeviceChanged", description, params); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::stateChanged, this, &NetworkManagerHandler::onNetworkManagerStatusChanged); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::networkingEnabledChanged, this, &NetworkManagerHandler::onNetworkManagerStatusChanged); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wirelessEnabledChanged, this, &NetworkManagerHandler::onNetworkManagerStatusChanged); + connect(m_networkManager, &NetworkManager::stateChanged, this, &NetworkManagerHandler::onNetworkManagerStatusChanged); + connect(m_networkManager, &NetworkManager::networkingEnabledChanged, this, &NetworkManagerHandler::onNetworkManagerStatusChanged); + connect(m_networkManager, &NetworkManager::wirelessEnabledChanged, this, &NetworkManagerHandler::onNetworkManagerStatusChanged); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wirelessDeviceAdded, this, &NetworkManagerHandler::onWirelessNetworkDeviceAdded); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wirelessDeviceRemoved, this, &NetworkManagerHandler::onWirelessNetworkDeviceRemoved); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wirelessDeviceChanged, this, &NetworkManagerHandler::onWirelessNetworkDeviceChanged); + connect(m_networkManager, &NetworkManager::wirelessDeviceAdded, this, &NetworkManagerHandler::onWirelessNetworkDeviceAdded); + connect(m_networkManager, &NetworkManager::wirelessDeviceRemoved, this, &NetworkManagerHandler::onWirelessNetworkDeviceRemoved); + connect(m_networkManager, &NetworkManager::wirelessDeviceChanged, this, &NetworkManagerHandler::onWirelessNetworkDeviceChanged); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wiredDeviceAdded, this, &NetworkManagerHandler::onWiredNetworkDeviceAdded); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wiredDeviceRemoved, this, &NetworkManagerHandler::onWiredNetworkDeviceRemoved); - connect(NymeaCore::instance()->networkManager(), &NetworkManager::wiredDeviceChanged, this, &NetworkManagerHandler::onWiredNetworkDeviceChanged); + connect(m_networkManager, &NetworkManager::wiredDeviceAdded, this, &NetworkManagerHandler::onWiredNetworkDeviceAdded); + connect(m_networkManager, &NetworkManager::wiredDeviceRemoved, this, &NetworkManagerHandler::onWiredNetworkDeviceRemoved); + connect(m_networkManager, &NetworkManager::wiredDeviceChanged, this, &NetworkManagerHandler::onWiredNetworkDeviceChanged); } /*! Returns the name of the \l{NetworkManagerHandler}. In this case \b NetworkManager. */ @@ -236,7 +249,7 @@ JsonReply *NetworkManagerHandler::GetNetworkStatus(const QVariantMap ¶ms) Q_UNUSED(params) // Check available - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); // Pack network manager status @@ -247,12 +260,12 @@ JsonReply *NetworkManagerHandler::GetNetworkStatus(const QVariantMap ¶ms) JsonReply *NetworkManagerHandler::EnableNetworking(const QVariantMap ¶ms) { - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); bool enable = params.value("enable").toBool(); - if (!NymeaCore::instance()->networkManager()->enableNetworking(enable)) + if (!m_networkManager->enableNetworking(enable)) return createReply(statusToReply(NetworkManager::NetworkManagerErrorUnknownError)); return createReply(statusToReply(NetworkManager::NetworkManagerErrorNoError)); @@ -260,13 +273,13 @@ JsonReply *NetworkManagerHandler::EnableNetworking(const QVariantMap ¶ms) JsonReply *NetworkManagerHandler::EnableWirelessNetworking(const QVariantMap ¶ms) { - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); - if (!NymeaCore::instance()->networkManager()->wirelessAvailable()) + if (!m_networkManager->wirelessAvailable()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNotAvailable)); - if (!NymeaCore::instance()->networkManager()->enableWireless(params.value("enable").toBool())) + if (!m_networkManager->enableWireless(params.value("enable").toBool())) return createReply(statusToReply(NetworkManager::NetworkManagerErrorUnknownError)); return createReply(statusToReply(NetworkManager::NetworkManagerErrorNoError)); @@ -274,24 +287,24 @@ JsonReply *NetworkManagerHandler::EnableWirelessNetworking(const QVariantMap &pa JsonReply *NetworkManagerHandler::GetWirelessAccessPoints(const QVariantMap ¶ms) { - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); - if (!NymeaCore::instance()->networkManager()->wirelessAvailable()) + if (!m_networkManager->wirelessAvailable()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNotAvailable)); - if (!NymeaCore::instance()->networkManager()->networkingEnabled()) + if (!m_networkManager->networkingEnabled()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkingDisabled)); - if (!NymeaCore::instance()->networkManager()->wirelessEnabled()) + if (!m_networkManager->wirelessEnabled()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNetworkingDisabled)); QString interface = params.value("interface").toString(); - if (!NymeaCore::instance()->networkManager()->getNetworkDevice(interface)) + if (!m_networkManager->getNetworkDevice(interface)) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkInterfaceNotFound)); - foreach (WirelessNetworkDevice *networkDevice, NymeaCore::instance()->networkManager()->wirelessNetworkDevices()) { + foreach (WirelessNetworkDevice *networkDevice, m_networkManager->wirelessNetworkDevices()) { if (networkDevice->interface() == interface) { QVariantList wirelessAccessPoints; foreach (WirelessAccessPoint *wirelessAccessPoint, networkDevice->accessPoints()) @@ -311,15 +324,15 @@ JsonReply *NetworkManagerHandler::GetNetworkDevices(const QVariantMap ¶ms) { Q_UNUSED(params) - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); QVariantList wirelessNetworkDevices; - foreach (WirelessNetworkDevice *networkDevice, NymeaCore::instance()->networkManager()->wirelessNetworkDevices()) + foreach (WirelessNetworkDevice *networkDevice, m_networkManager->wirelessNetworkDevices()) wirelessNetworkDevices.append(packWirelessNetworkDevice(networkDevice)); QVariantList wiredNetworkDevices; - foreach (WiredNetworkDevice *networkDevice, NymeaCore::instance()->networkManager()->wiredNetworkDevices()) + foreach (WiredNetworkDevice *networkDevice, m_networkManager->wiredNetworkDevices()) wiredNetworkDevices.append(packWiredNetworkDevice(networkDevice)); QVariantMap returns = statusToReply(NetworkManager::NetworkManagerErrorNoError); @@ -332,25 +345,25 @@ JsonReply *NetworkManagerHandler::ScanWifiNetworks(const QVariantMap ¶ms) { Q_UNUSED(params) - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); - if (!NymeaCore::instance()->networkManager()->wirelessAvailable()) + if (!m_networkManager->wirelessAvailable()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNotAvailable)); - if (!NymeaCore::instance()->networkManager()->networkingEnabled()) + if (!m_networkManager->networkingEnabled()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkingDisabled)); - if (!NymeaCore::instance()->networkManager()->wirelessEnabled()) + if (!m_networkManager->wirelessEnabled()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNetworkingDisabled)); QString interface = params.value("interface").toString(); - if (!NymeaCore::instance()->networkManager()->getNetworkDevice(interface)) + if (!m_networkManager->getNetworkDevice(interface)) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkInterfaceNotFound)); - foreach (WirelessNetworkDevice *networkDevice, NymeaCore::instance()->networkManager()->wirelessNetworkDevices()) { + foreach (WirelessNetworkDevice *networkDevice, m_networkManager->wirelessNetworkDevices()) { if (networkDevice->interface() == interface) { networkDevice->scanWirelessNetworks(); return createReply(statusToReply(NetworkManager::NetworkManagerErrorNoError)); @@ -362,16 +375,16 @@ JsonReply *NetworkManagerHandler::ScanWifiNetworks(const QVariantMap ¶ms) JsonReply *NetworkManagerHandler::ConnectWifiNetwork(const QVariantMap ¶ms) { - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); - if (!NymeaCore::instance()->networkManager()->wirelessAvailable()) + if (!m_networkManager->wirelessAvailable()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNotAvailable)); - if (!NymeaCore::instance()->networkManager()->networkingEnabled()) + if (!m_networkManager->networkingEnabled()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkingDisabled)); - if (!NymeaCore::instance()->networkManager()->wirelessEnabled()) + if (!m_networkManager->wirelessEnabled()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorWirelessNetworkingDisabled)); @@ -379,16 +392,16 @@ JsonReply *NetworkManagerHandler::ConnectWifiNetwork(const QVariantMap ¶ms) QString password = params.value("password").toString(); QString interface = params.value("interface").toString(); - return createReply(statusToReply(NymeaCore::instance()->networkManager()->connectWifi(interface, ssid, password))); + return createReply(statusToReply(m_networkManager->connectWifi(interface, ssid, password))); } JsonReply *NetworkManagerHandler::DisconnectInterface(const QVariantMap ¶ms) { - if (!NymeaCore::instance()->networkManager()->available()) + if (!m_networkManager->available()) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); QString interface = params.value("interface").toString(); - NetworkDevice *networkDevice = NymeaCore::instance()->networkManager()->getNetworkDevice(interface); + NetworkDevice *networkDevice = m_networkManager->getNetworkDevice(interface); if (!networkDevice) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkInterfaceNotFound)); @@ -396,12 +409,25 @@ JsonReply *NetworkManagerHandler::DisconnectInterface(const QVariantMap ¶ms) return createReply(statusToReply(NetworkManager::NetworkManagerErrorNoError)); } +JsonReply *NetworkManagerHandler::StartAccessPoint(const QVariantMap ¶ms) +{ + if (!m_networkManager->available()) { + return createReply(statusToReply(NetworkManager::NetworkManagerErrorNetworkManagerNotAvailable)); + } + + QString interface = params.value("interface").toString(); + QString ssid = params.value("ssid").toString(); + QString password = params.value("password").toString(); + NetworkManager::NetworkManagerError status = m_networkManager->startAccessPoint(interface, ssid, password); + return createReply(statusToReply(status)); +} + QVariantMap NetworkManagerHandler::packNetworkManagerStatus() { QVariantMap status; - status.insert("networkingEnabled", NymeaCore::instance()->networkManager()->networkingEnabled()); - status.insert("wirelessNetworkingEnabled", NymeaCore::instance()->networkManager()->wirelessEnabled()); - status.insert("state", NymeaCore::instance()->networkManager()->stateString()); + status.insert("networkingEnabled", m_networkManager->networkingEnabled()); + status.insert("wirelessNetworkingEnabled", m_networkManager->wirelessEnabled()); + status.insert("state", m_networkManager->stateString()); return status; } @@ -470,6 +496,8 @@ QVariantMap NetworkManagerHandler::packWiredNetworkDevice(WiredNetworkDevice *ne QVariantMap networkDeviceVariant; networkDeviceVariant.insert("interface", networkDevice->interface()); networkDeviceVariant.insert("macAddress", networkDevice->macAddress()); + networkDeviceVariant.insert("ipv4Addresses", networkDevice->ipv4Addresses()); + networkDeviceVariant.insert("ipv6Addresses", networkDevice->ipv6Addresses()); networkDeviceVariant.insert("state", networkDevice->deviceStateString()); networkDeviceVariant.insert("bitRate", QString("%1 [Mb/s]").arg(QString::number(networkDevice->bitRate()))); networkDeviceVariant.insert("pluggedIn", networkDevice->pluggedIn()); @@ -481,7 +509,10 @@ QVariantMap NetworkManagerHandler::packWirelessNetworkDevice(WirelessNetworkDevi QVariantMap networkDeviceVariant; networkDeviceVariant.insert("interface", networkDevice->interface()); networkDeviceVariant.insert("macAddress", networkDevice->macAddress()); + networkDeviceVariant.insert("ipv4Addresses", networkDevice->ipv4Addresses()); + networkDeviceVariant.insert("ipv6Addresses", networkDevice->ipv6Addresses()); networkDeviceVariant.insert("state", networkDevice->deviceStateString()); + networkDeviceVariant.insert("mode", enumValueName(networkDevice->wirelessMode())); networkDeviceVariant.insert("bitRate", QString("%1 [Mb/s]").arg(QString::number(networkDevice->bitRate()))); if (networkDevice->activeAccessPoint()) networkDeviceVariant.insert("currentAccessPoint", packWirelessAccessPoint(networkDevice->activeAccessPoint())); diff --git a/libnymea-core/jsonrpc/networkmanagerhandler.h b/libnymea-core/jsonrpc/networkmanagerhandler.h index 5d0340d1..d09445ab 100644 --- a/libnymea-core/jsonrpc/networkmanagerhandler.h +++ b/libnymea-core/jsonrpc/networkmanagerhandler.h @@ -42,7 +42,7 @@ class NetworkManagerHandler : public JsonHandler { Q_OBJECT public: - explicit NetworkManagerHandler(QObject *parent = nullptr); + explicit NetworkManagerHandler(NetworkManager *networkManager, QObject *parent = nullptr); QString name() const; @@ -54,6 +54,7 @@ public: Q_INVOKABLE JsonReply *ScanWifiNetworks(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *ConnectWifiNetwork(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *DisconnectInterface(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply *StartAccessPoint(const QVariantMap ¶ms); private: QVariantMap packNetworkManagerStatus(); @@ -91,6 +92,8 @@ private: QVariantMap statusToReply(NetworkManager::NetworkManagerError status) const; + NetworkManager* m_networkManager = nullptr; + }; } diff --git a/tests/auto/api.json b/tests/auto/api.json index b34cbf37..9d48436d 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -358,6 +358,12 @@ "ValueOperatorGreater", "ValueOperatorLessOrEqual", "ValueOperatorGreaterOrEqual" + ], + "WirelessMode": [ + "WirelessModeUnknown", + "WirelessModeAdhoc", + "WirelessModeInfrastructure", + "WirelessModeAccessPoint" ] }, "flags": { @@ -1487,6 +1493,17 @@ "networkManagerError": "$ref:NetworkManagerError" } }, + "NetworkManager.StartAccessPoint": { + "description": "Start a WiFi Access point on the given interface with the given SSID and password. Use DisconnectInterface to stop it again.", + "params": { + "interface": "String", + "password": "String", + "ssid": "String" + }, + "returns": { + "networkManagerError": "$ref:NetworkManagerError" + } + }, "Rules.AddRule": { "description": "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that only one of either eventDescriptor or eventDescriptorList may be passed at a time. A rule can be created but left disabled, meaning it won't actually be executed until set to enabled. If not given, enabled defaults to true. A rule can have a list of actions and exitActions. It must have at least one Action. For state based rules, actions will be executed when the system enters a state matching the stateDescriptor. The exitActions will be executed when the system leaves the described state again. For event based rules, actions will be executed when a matching event happens and if the stateEvaluator matches the system's state. ExitActions for such rules will be executed when a matching event happens and the stateEvaluator is not matching the system's state. A rule marked as executable can be executed via the API using Rules.ExecuteRule, that means, its actions will be executed regardless of the eventDescriptor and stateEvaluators.", "params": { @@ -2765,6 +2782,8 @@ "WiredNetworkDevice": { "r:bitRate": "String", "r:interface": "String", + "r:ipv4Addresses": "StringList", + "r:ipv6Addresses": "StringList", "r:macAddress": "String", "r:pluggedIn": "Bool", "r:state": "$ref:NetworkDeviceState" @@ -2777,11 +2796,14 @@ "r:ssid": "String" }, "WirelessNetworkDevice": { - "bitRate": "String", - "interface": "String", - "macAddress": "String", - "o:currentAccessPoint": "$ref:WirelessAccessPoint", - "state": "$ref:NetworkDeviceState" + "r:bitRate": "String", + "r:interface": "String", + "r:ipv4Addresses": "StringList", + "r:ipv6Addresses": "StringList", + "r:macAddress": "String", + "r:mode": "$ref:WirelessMode", + "r:o:currentAccessPoint": "$ref:WirelessAccessPoint", + "r:state": "$ref:NetworkDeviceState" } } }