diff --git a/libnymea-networkmanager/networkdevice.h b/libnymea-networkmanager/networkdevice.h index dbc54bb..222f069 100644 --- a/libnymea-networkmanager/networkdevice.h +++ b/libnymea-networkmanager/networkdevice.h @@ -55,6 +55,7 @@ public: NetworkDeviceStateDeactivating = 110, NetworkDeviceStateFailed = 120 }; + Q_ENUM(NetworkDeviceState) enum NetworkDeviceStateReason { NetworkDeviceStateReasonNone = 0, @@ -121,6 +122,7 @@ public: NetworkDeviceStateReasonParentChanged = 61, NetworkDeviceStateReasonParentManagedChanged = 62 }; + Q_ENUM(NetworkDeviceStateReason) enum NetworkDeviceType { NetworkDeviceTypeUnknown = 0, @@ -143,6 +145,7 @@ public: NetworkDeviceTypeVXLan = 19, NetworkDeviceTypeVEth = 20, }; + Q_ENUM(NetworkDeviceType) explicit NetworkDevice(const QDBusObjectPath &objectPath, QObject *parent = 0); diff --git a/libnymea-networkmanager/networkmanager.cpp b/libnymea-networkmanager/networkmanager.cpp index 4d4027b..9a8fcce 100644 --- a/libnymea-networkmanager/networkmanager.cpp +++ b/libnymea-networkmanager/networkmanager.cpp @@ -127,7 +127,7 @@ NetworkManager::NetworkManagerError NetworkManager::connectWifi(const QString &i QVariantMap connectionSettings; connectionSettings.insert("autoconnect", true); - connectionSettings.insert("id", ssid + " (loop)"); + connectionSettings.insert("id", ssid); connectionSettings.insert("uuid", QUuid::createUuid().toString().remove("{").remove("}")); connectionSettings.insert("type", "802-11-wireless"); @@ -229,25 +229,6 @@ bool NetworkManager::enableWireless(bool enabled) return m_networkManagerInterface->setProperty("WirelessEnabled", enabled); } -bool NetworkManager::isConnectedToLan() const -{ - // Check all wireless devices if one is connected - foreach (WirelessNetworkDevice *wirelessDevice, wirelessNetworkDevices()) { - if (wirelessDevice->deviceState() == NetworkDevice::NetworkDeviceStateActivated) { - return true; - } - } - - // Check all wired devices if one is connected - foreach (WiredNetworkDevice *wiredDevice, wiredNetworkDevices()) { - if (wiredDevice->deviceState() == NetworkDevice::NetworkDeviceStateActivated) { - return true; - } - } - - return false; -} - void NetworkManager::loadDevices() { // Get network devices @@ -312,7 +293,7 @@ void NetworkManager::setWirelessEnabled(bool enabled) qCDebug(dcNetworkManager()) << "Wireless networking" << (enabled ? "enabled" : "disabled"); m_wirelessEnabled = enabled; - emit wirelessEnabledChanged(); + emit wirelessEnabledChanged(m_wirelessEnabled); } void NetworkManager::setConnectivityState(const NetworkManager::NetworkManagerConnectivityState &connectivityState) @@ -322,7 +303,7 @@ void NetworkManager::setConnectivityState(const NetworkManager::NetworkManagerCo qCDebug(dcNetworkManager()) << "Connectivity state changed:" << networkManagerConnectivityStateToString(connectivityState); m_connectivityState = connectivityState; - emit connectivityStateChanged(); + emit connectivityStateChanged(m_connectivityState); } void NetworkManager::setState(const NetworkManager::NetworkManagerState &state) @@ -332,7 +313,7 @@ void NetworkManager::setState(const NetworkManager::NetworkManagerState &state) qCDebug(dcNetworkManager()) << "State changed:" << networkManagerStateToString(state); m_state = state; - emit stateChanged(); + emit stateChanged(m_state); } void NetworkManager::onServiceRegistered() @@ -408,7 +389,7 @@ void NetworkManager::onDeviceRemoved(const QDBusObjectPath &deviceObjectPath) qCDebug(dcNetworkManager()) << "[-]" << m_wirelessNetworkDevices.value(deviceObjectPath); m_wirelessNetworkDevices.remove(deviceObjectPath); if (!wirelessAvailable()) - emit wirelessAvailableChanged(); + emit wirelessAvailableChanged(wirelessAvailable()); emit wirelessDeviceRemoved(networkDevice->interface()); } else { diff --git a/libnymea-networkmanager/networkmanager.h b/libnymea-networkmanager/networkmanager.h index f09c5c0..351f698 100644 --- a/libnymea-networkmanager/networkmanager.h +++ b/libnymea-networkmanager/networkmanager.h @@ -55,14 +55,16 @@ public: NetworkManagerStateConnectedSite = 60, NetworkManagerStateConnectedGlobal = 70 }; + Q_ENUM(NetworkManagerState) enum NetworkManagerConnectivityState { - NetworkManagerConnectivityStateUnknown = 1, - NetworkManagerConnectivityStateNone = 2, - NetworkManagerConnectivityStatePortal = 3, - NetworkManagerConnectivityStateLimited = 4, - NetworkManagerConnectivityStateFull = 5 + NetworkManagerConnectivityStateUnknown = 0, + NetworkManagerConnectivityStateNone = 1, + NetworkManagerConnectivityStatePortal = 2, + NetworkManagerConnectivityStateLimited = 3, + NetworkManagerConnectivityStateFull = 4 }; + Q_ENUM(NetworkManagerConnectivityState) enum NetworkManagerError { NetworkManagerErrorNoError, @@ -76,6 +78,7 @@ public: NetworkManagerErrorNetworkingDisabled, NetworkManagerErrorNetworkManagerNotAvailable }; + Q_ENUM(NetworkManagerError) explicit NetworkManager(QObject *parent = 0); ~NetworkManager(); @@ -105,10 +108,6 @@ public: bool wirelessEnabled() const; bool enableWireless(bool enabled); - // Status methods - bool isConnectedToLan() const; - bool isOnline() const; - private: QDBusServiceWatcher *m_serviceWatcher = nullptr; QDBusInterface *m_networkManagerInterface = nullptr; @@ -119,9 +118,7 @@ private: QHash m_wiredNetworkDevices; bool m_available = false; - QString m_version; - NetworkManagerState m_state = NetworkManagerStateUnknown; NetworkManagerConnectivityState m_connectivityState = NetworkManagerConnectivityStateUnknown; bool m_networkingEnabled = false; @@ -143,10 +140,10 @@ signals: void availableChanged(bool available); void versionChanged(const QString &version); void networkingEnabledChanged(bool enabled); - void wirelessEnabledChanged(); - void wirelessAvailableChanged(); - void stateChanged(); - void connectivityStateChanged(); + void wirelessEnabledChanged(bool enabled); + void wirelessAvailableChanged(bool available); + void stateChanged(const NetworkManagerState &state); + void connectivityStateChanged(const NetworkManagerConnectivityState &state); void wirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice); void wirelessDeviceRemoved(const QString &interface); diff --git a/libnymea-networkmanager/wirelessaccesspoint.h b/libnymea-networkmanager/wirelessaccesspoint.h index 83cc800..fd0f735 100644 --- a/libnymea-networkmanager/wirelessaccesspoint.h +++ b/libnymea-networkmanager/wirelessaccesspoint.h @@ -36,7 +36,7 @@ class WirelessAccessPoint : public QObject Q_FLAGS(ApSecurityModes) public: - enum ApSecurityMode{ + enum ApSecurityMode { ApSecurityModeNone = 0x000, ApSecurityModePairWep40 = 0x001, ApSecurityModePairWep104 = 0x002, @@ -51,7 +51,6 @@ public: }; Q_DECLARE_FLAGS(ApSecurityModes, ApSecurityMode) - explicit WirelessAccessPoint(const QDBusObjectPath &objectPath, QObject *parent = 0); QDBusObjectPath objectPath() const; diff --git a/nymea-networkmanager/bluetooth/bluetoothserver.cpp b/nymea-networkmanager/bluetooth/bluetoothserver.cpp index df1ef17..eb7b9bb 100644 --- a/nymea-networkmanager/bluetooth/bluetoothserver.cpp +++ b/nymea-networkmanager/bluetooth/bluetoothserver.cpp @@ -155,7 +155,7 @@ QLowEnergyServiceData BluetoothServer::genericAttributeServiceData() return serviceData; } -void BluetoothServer::setRunning(const bool &running) +void BluetoothServer::setRunning(bool running) { if (m_running == running) return; @@ -164,7 +164,7 @@ void BluetoothServer::setRunning(const bool &running) emit runningChanged(m_running); } -void BluetoothServer::setConnected(const bool &connected) +void BluetoothServer::setConnected(bool connected) { if (m_connected == connected) return; @@ -218,7 +218,6 @@ void BluetoothServer::onDisconnected() { qCDebug(dcBluetoothServer()) << "Client disconnected"; setConnected(false); - stop(); } void BluetoothServer::onControllerStateChanged(const QLowEnergyController::ControllerState &state) @@ -367,14 +366,14 @@ void BluetoothServer::start(WirelessNetworkDevice *wirelessDevice) QLowEnergyAdvertisingData advertisingData; advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral); advertisingData.setIncludePowerLevel(true); - advertisingData.setLocalName("Loop-box"); + advertisingData.setLocalName("nymea"); // TODO: set guh manufacturer SIG data // Note: start advertising in 100 ms interval, this makes the device better discoverable on certain phones QLowEnergyAdvertisingParameters advertisingParameters; advertisingParameters.setInterval(100,100); - qCDebug(dcBluetoothServer()) << "Start advertising loopd" << m_localDevice->address().toString(); + qCDebug(dcBluetoothServer()) << "Start advertising" << advertisingData.localName() << m_localDevice->address().toString(); m_controller->startAdvertising(advertisingParameters, advertisingData, advertisingData); } @@ -385,6 +384,9 @@ void BluetoothServer::stop() return; } + if (!running()) + return; + qCDebug(dcBluetoothServer()) << "-------------------------------------"; qCDebug(dcBluetoothServer()) << "Stopping bluetooth server."; qCDebug(dcBluetoothServer()) << "-------------------------------------"; diff --git a/nymea-networkmanager/bluetooth/bluetoothserver.h b/nymea-networkmanager/bluetooth/bluetoothserver.h index 75541ed..7876b79 100644 --- a/nymea-networkmanager/bluetooth/bluetoothserver.h +++ b/nymea-networkmanager/bluetooth/bluetoothserver.h @@ -72,12 +72,12 @@ private: QLowEnergyServiceData genericAccessServiceData(); QLowEnergyServiceData genericAttributeServiceData(); - void setRunning(const bool &running); - void setConnected(const bool &connected); + void setRunning(bool running); + void setConnected(bool connected); signals: - void runningChanged(const bool &running); - void connectedChanged(const bool &connected); + void runningChanged(bool running); + void connectedChanged(bool connected); private slots: // Local bluetooth device diff --git a/nymea-networkmanager/core.cpp b/nymea-networkmanager/core.cpp index 75efe63..7ea54d1 100644 --- a/nymea-networkmanager/core.cpp +++ b/nymea-networkmanager/core.cpp @@ -45,23 +45,40 @@ NetworkManager *Core::networkManager() const return m_networkManager; } +BluetoothServer *Core::bluetoothServer() const +{ + return m_bluetoothServer; +} + +NymeadService *Core::nymeaService() const +{ + return m_nymeaService; +} + Core::Core(QObject *parent) : QObject(parent) { m_networkManager = new NetworkManager(this); connect(m_networkManager, &NetworkManager::availableChanged, this, &Core::onNetworkManagerAvailableChanged); + connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged); - m_bluetoothServer = new BluetoothServer("nymea", this); + m_bluetoothServer = new BluetoothServer("nymea-box", this); + connect(m_bluetoothServer, &BluetoothServer::runningChanged, this, &Core::onBluetoothServerRunningChanged); + connect(m_bluetoothServer, &BluetoothServer::connectedChanged, this, &Core::onBluetoothServerConnectedChanged); m_nymeaService = new NymeadService(false, this); + // Start the networkmanager service if (!m_networkManager->start()) { - qCWarning(dcApplication()) << "Could not start network manager."; + qCWarning(dcApplication()) << "Could not start network manager. The service is not available. Make sure the network-manager is installed and running."; } } Core::~Core() { + delete m_nymeaService; + m_nymeaService = nullptr; + delete m_networkManager; m_networkManager = nullptr; @@ -69,12 +86,80 @@ Core::~Core() m_bluetoothServer = nullptr; } +void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state) +{ + switch (state) { + case NetworkManager::NetworkManagerStateConnectedGlobal: + // We are online + stopService(); + break; + case NetworkManager::NetworkManagerStateConnectedSite: + // We somehow in the network + stopService(); + break; + default: + // Everything else is not connected, start the service + startService(); + break; + } +} + +void Core::startService() +{ + if (!m_networkManager->available()) + return; + + // Verify if we have a wireless network available + if (!m_networkManager->wirelessAvailable()) { + qCWarning(dcApplication()) << "Could not start services. There is no wireless device available."; + return; + } + + // Disable bluetooth on nymea in order to not crash with client connections + m_nymeaService->enableBluetooth(false); + + // Start the bluetooth server for this wireless device + qCDebug(dcApplication()) << "Start bluetooth service"; + m_bluetoothServer->start(m_networkManager->wirelessNetworkDevices().first()); +} + +void Core::stopService() +{ + if (m_bluetoothServer->running()) + qCDebug(dcApplication()) << "Stop bluetooth service"; + + m_bluetoothServer->stop(); +} + +void Core::onBluetoothServerRunningChanged(bool running) +{ + qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped"); + + if (!running) { + // Enable bluetooth on nymea + m_nymeaService->enableBluetooth(true); + } +} + +void Core::onBluetoothServerConnectedChanged(bool connected) +{ + qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected"); +} + void Core::onNetworkManagerAvailableChanged(const bool &available) { if (!available) { qCWarning(dcApplication()) << "Networkmanager is not available any more."; - } else { - qCDebug(dcApplication()) << "Networkmanager is now available."; - + stopService(); + return; } + + qCDebug(dcApplication()) << "Networkmanager is now available."; + evaluateNetworkManagerState(m_networkManager->state()); +} + +void Core::onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state) +{ + qCDebug(dcApplication()) << state; + evaluateNetworkManagerState(state); } diff --git a/nymea-networkmanager/core.h b/nymea-networkmanager/core.h index fe319aa..0bed2ec 100644 --- a/nymea-networkmanager/core.h +++ b/nymea-networkmanager/core.h @@ -36,6 +36,8 @@ public: void destroy(); NetworkManager *networkManager() const; + BluetoothServer *bluetoothServer() const; + NymeadService *nymeaService() const; private: explicit Core(QObject *parent = nullptr); @@ -47,8 +49,17 @@ private: BluetoothServer *m_bluetoothServer = nullptr; NymeadService *m_nymeaService = nullptr; + void evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state); + + void startService(); + void stopService(); + private slots: + void onBluetoothServerRunningChanged(bool running); + void onBluetoothServerConnectedChanged(bool connected); + void onNetworkManagerAvailableChanged(const bool &available); + void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state); }; diff --git a/nymea-networkmanager/main.cpp b/nymea-networkmanager/main.cpp index 7286dbb..6ff3e92 100644 --- a/nymea-networkmanager/main.cpp +++ b/nymea-networkmanager/main.cpp @@ -88,15 +88,15 @@ int main(int argc, char *argv[]) parser.addVersionOption(); parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection.\n\nCopyright %1 2018 Simon Stürz ").arg(QChar(0xA9))); - // TODO: set options - + QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output."); + parser.addOption(debugOption); parser.process(application); // Enable debug categories s_loggingFilters.insert("Application", true); - s_loggingFilters.insert("BluetoothServer", true); - s_loggingFilters.insert("NetworkManager", true); - s_loggingFilters.insert("NymeaService", true); + s_loggingFilters.insert("BluetoothServer", parser.isSet(debugOption)); + s_loggingFilters.insert("NetworkManager", parser.isSet(debugOption) ); + s_loggingFilters.insert("NymeaService", parser.isSet(debugOption)); QLoggingCategory::installFilter(loggingCategoryFilter); diff --git a/nymea-networkmanager/nymeadservice.cpp b/nymea-networkmanager/nymeadservice.cpp index 5cc6ba1..abe7085 100644 --- a/nymea-networkmanager/nymeadservice.cpp +++ b/nymea-networkmanager/nymeadservice.cpp @@ -32,7 +32,7 @@ bool NymeadService::available() const void NymeadService::enableBluetooth(const bool &enable) { if (!m_nymeadHardwareInterface) { - qCCritical(dcNymeaService()) << "Could not enable/disable bluetooth hardware resource. D-Bus interface not available."; + qCWarning(dcNymeaService()) << "Could not enable/disable bluetooth hardware resource. D-Bus interface not available."; return; } @@ -48,7 +48,7 @@ void NymeadService::enableBluetooth(const bool &enable) void NymeadService::pushButtonPressed() { if (!m_pushButtonAgent) { - qCCritical(dcNymeaService()) << "Could not press pushbutton. Pushbutton agent not available."; + qCWarning(dcNymeaService()) << "Could not press pushbutton. Pushbutton agent not available."; return; } diff --git a/nymea-networkmanager/pushbuttonagent.cpp b/nymea-networkmanager/pushbuttonagent.cpp index 7318326..0625632 100644 --- a/nymea-networkmanager/pushbuttonagent.cpp +++ b/nymea-networkmanager/pushbuttonagent.cpp @@ -14,14 +14,14 @@ bool PushButtonAgent::init(QDBusConnection::BusType busType) { QDBusConnection bus = busType == QDBusConnection::SessionBus ? QDBusConnection::sessionBus() : QDBusConnection::systemBus(); - bool result = bus.registerObject("/io/guh/loopd/pushbutton", this, QDBusConnection::ExportScriptableContents); + bool result = bus.registerObject("/io/nymea/nymea-networkmanager/pushbutton", this, QDBusConnection::ExportScriptableContents); if (!result) { qCWarning(dcNymeaService()) << "PushButtonAgent: Error registering PushButton agent on D-Bus."; return false; } QDBusMessage message = QDBusMessage::createMethodCall("io.guh.nymead", "/io/guh/nymead/UserManager", QString(), "RegisterButtonAgent"); - message << qVariantFromValue(QDBusObjectPath("/io/guh/loopd/pushbutton")); + message << qVariantFromValue(QDBusObjectPath("/io/nymea/nymea-networkmanager/pushbutton")); QDBusMessage reply = bus.call(message); if (!reply.errorName().isEmpty()) { qCWarning(dcNymeaService()) << "PushButtonAgent: Error registering PushButton agent:" << reply.errorMessage();