diff --git a/README.md b/README.md index 0b1257c..c92335f 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ this repository and it will be installed to /etc/nymea-networkmanager.conf with -m, --mode Run the daemon in a specific mode (offline, once, always, button, start). Default is "offline". + -b, --dbus-type If given, a DBus interface will be exposed on + the chosen DBus bus type (session, system) diff --git a/nymea-networkmanager.conf b/nymea-networkmanager.conf index a6753c2..313eeef 100644 --- a/nymea-networkmanager.conf +++ b/nymea-networkmanager.conf @@ -4,3 +4,4 @@ Timeout=60 AdvertiseName=BT WLAN setup PlatformName=nymea-box ButtonGpio=14 +DBusBusType=system diff --git a/nymea-networkmanager/application.cpp b/nymea-networkmanager/application.cpp index b5fb2a5..8add558 100644 --- a/nymea-networkmanager/application.cpp +++ b/nymea-networkmanager/application.cpp @@ -29,7 +29,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "application.h" -#include "loggingcategories.h" #include "core.h" #include @@ -67,7 +66,6 @@ static void catchUnixSignals(const std::vector& quitSignals, const std::vec qCDebug(dcApplication()) << "====================================="; s_aboutToShutdown = true; - Core::instance()->destroy(); Application::quit(); }; diff --git a/nymea-networkmanager/core.cpp b/nymea-networkmanager/core.cpp index 19261d1..d4b5d5d 100644 --- a/nymea-networkmanager/core.cpp +++ b/nymea-networkmanager/core.cpp @@ -29,27 +29,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "core.h" -#include "loggingcategories.h" +#include "nymeanetworkmanagerdbusservice.h" #include -Core* Core::s_instance = nullptr; - -Core *Core::instance() -{ - if (!s_instance) - s_instance = new Core(); - - return s_instance; -} - -void Core::destroy() -{ - if (s_instance) - delete s_instance; - - s_instance = nullptr; -} +Q_LOGGING_CATEGORY(dcApplication, "Application") NetworkManager *Core::networkManager() const { @@ -106,14 +90,18 @@ void Core::setAdvertisingTimeout(int advertisingTimeout) m_advertisingTimeout = advertisingTimeout; } -int Core::buttonGpio() const +void Core::addGPioButton(int buttonGpio) { - return m_buttonGpio; + GpioButton *button = new GpioButton(buttonGpio, this); + button->setLongPressedTimeout(2000); + connect(button, &GpioButton::longPressed, this, &Core::startService); + m_buttons.append(button); } -void Core::setButtonGpio(int buttonGpio) +void Core::enableDBusInterface(QDBusConnection::BusType busType) { - m_buttonGpio = buttonGpio; + NymeaNetworkManagerDBusService *dbusService = new NymeaNetworkManagerDBusService(busType, this); + connect(dbusService, &NymeaNetworkManagerDBusService::enableBluetoothServerCalled, this, &Core::startService); } void Core::run() @@ -140,10 +128,6 @@ Core::Core(QObject *parent) : m_advertisingTimer = new QTimer(this); m_advertisingTimer->setSingleShot(true); connect(m_advertisingTimer, &QTimer::timeout, this, &Core::onAdvertisingTimeout); - - m_button = new GpioButton(m_buttonGpio, this); - m_button->setLongPressedTimeout(2000); - connect(m_button, &GpioButton::longPressed, this, &Core::onButtonLongPressed); } Core::~Core() @@ -290,8 +274,8 @@ void Core::onBluetoothServerConnectedChanged(bool connected) qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected"); m_advertisingTimer->stop(); - if (!connected) { - m_advertisingTimer->stop(); + if (!connected && m_mode != ModeAlways) { + m_bluetoothServer->stop(); } } @@ -332,8 +316,10 @@ void Core::onNetworkManagerAvailableChanged(bool available) } break; case ModeButton: - if (!m_button->enable()) { - qCCritical(dcApplication()) << "Failed to enable the GPIO button for" << m_buttonGpio; + foreach (GpioButton* button, m_buttons) { + if (!button->enable()) { + qCCritical(dcApplication()) << "Failed to enable the GPIO button for" << button->gpioNumber(); + } } break; } @@ -344,11 +330,6 @@ void Core::onNetworkManagerStateChanged(NetworkManager::NetworkManagerState stat evaluateNetworkManagerState(state); } -void Core::onButtonLongPressed() -{ - startService(); -} - void Core::onNymeaServiceAvailableChanged(bool available) { if (available) diff --git a/nymea-networkmanager/core.h b/nymea-networkmanager/core.h index 47fc34d..274a9c4 100644 --- a/nymea-networkmanager/core.h +++ b/nymea-networkmanager/core.h @@ -39,10 +39,14 @@ #include "networkmanager.h" #include "bluetooth/bluetoothserver.h" +Q_DECLARE_LOGGING_CATEGORY(dcApplication) + class Core : public QObject { Q_OBJECT public: + explicit Core(QObject *parent = nullptr); + ~Core(); enum Mode { ModeAlways, @@ -53,9 +57,6 @@ public: }; Q_ENUM(Mode) - static Core* instance(); - void destroy(); - NetworkManager *networkManager() const; BluetoothServer *bluetoothServer() const; NymeadService *nymeaService() const; @@ -72,22 +73,17 @@ public: int advertisingTimeout() const; void setAdvertisingTimeout(int advertisingTimeout); - int buttonGpio() const; - void setButtonGpio(int buttonGpio); + void addGPioButton(int buttonGpio); + void enableDBusInterface(QDBusConnection::BusType busType); void run(); private: - explicit Core(QObject *parent = nullptr); - ~Core(); - - static Core *s_instance; - NetworkManager *m_networkManager = nullptr; BluetoothServer *m_bluetoothServer = nullptr; NymeadService *m_nymeaService = nullptr; WirelessNetworkDevice *m_wirelessDevice = nullptr; - GpioButton *m_button = nullptr; + QList m_buttons; QTimer *m_advertisingTimer = nullptr; @@ -95,7 +91,6 @@ private: QString m_advertiseName; QString m_platformName; int m_advertisingTimeout = 60; - int m_buttonGpio = -1; void evaluateNetworkManagerState(NetworkManager::NetworkManagerState state); @@ -111,8 +106,6 @@ private slots: void onNetworkManagerAvailableChanged(bool available); void onNetworkManagerStateChanged(NetworkManager::NetworkManagerState state); - void onButtonLongPressed(); - void onNymeaServiceAvailableChanged(bool available); }; diff --git a/nymea-networkmanager/loggingcategories.cpp b/nymea-networkmanager/loggingcategories.cpp deleted file mode 100644 index 5c74cc6..0000000 --- a/nymea-networkmanager/loggingcategories.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "loggingcategories.h" - -Q_LOGGING_CATEGORY(dcApplication, "Application") -Q_LOGGING_CATEGORY(dcNymeaService, "NymeaService") diff --git a/nymea-networkmanager/loggingcategories.h b/nymea-networkmanager/loggingcategories.h deleted file mode 100644 index 46ccaff..0000000 --- a/nymea-networkmanager/loggingcategories.h +++ /dev/null @@ -1,40 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef LOGGINGCATEGORIES_H -#define LOGGINGCATEGORIES_H - -#include -#include - -Q_DECLARE_LOGGING_CATEGORY(dcApplication) -Q_DECLARE_LOGGING_CATEGORY(dcNymeaService) - -#endif // LOGGINGCATEGORIES_H diff --git a/nymea-networkmanager/main.cpp b/nymea-networkmanager/main.cpp index 4823d94..9e68aaa 100644 --- a/nymea-networkmanager/main.cpp +++ b/nymea-networkmanager/main.cpp @@ -38,7 +38,6 @@ #include "core.h" #include "application.h" -#include "loggingcategories.h" static const char *const normal = "\033[0m"; static const char *const warning = "\e[33m"; @@ -96,6 +95,7 @@ int main(int argc, char *argv[]) int buttonGpio = -1; QString advertiseName = "BT WLAN setup"; QString platformName = "nymea-box"; + QString dbusBusType; Application application(argc, argv); application.setApplicationName("nymea-networkmanager"); @@ -140,6 +140,9 @@ int main(int argc, char *argv[]) QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode (offline, once, always, button, start). Default is \"offline\".", "MODE"); parser.addOption(modeOption); + QCommandLineOption dbusBusTypeOption({"b", "dbus-type"}, "If given, a DBus interface will be exposed on the chosen DBus bus type (session, system)", "DBUSTYPE"); + parser.addOption(dbusBusTypeOption); + parser.process(application); // Enable debug categories @@ -147,6 +150,7 @@ int main(int argc, char *argv[]) s_loggingFilters.insert("NymeaService", parser.isSet(debugOption)); s_loggingFilters.insert("NetworkManager", parser.isSet(debugOption) ); s_loggingFilters.insert("NetworkManagerBluetoothServer", parser.isSet(debugOption)); + s_loggingFilters.insert("DBus", parser.isSet(debugOption)); QLoggingCategory::installFilter(loggingCategoryFilter); @@ -190,6 +194,9 @@ int main(int argc, char *argv[]) if (settings.contains("PlatformName")) { platformName = settings.value("PlatformName").toString(); } + if (settings.contains("DBusBusType")) { + dbusBusType = settings.value("DBusBusType").toString(); + } break; } } @@ -224,6 +231,9 @@ int main(int argc, char *argv[]) if (parser.isSet(gpioOption)) { buttonGpio = parser.value(gpioOption).toInt(&gpioValueOk); } + if (parser.isSet(dbusBusTypeOption)) { + dbusBusType = parser.value(dbusBusTypeOption); + } // All parsed. Validate input: if (!timeoutValueOk) { @@ -238,10 +248,12 @@ int main(int argc, char *argv[]) qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". The minimal timeout is 10 [s].").arg(parser.value(timeoutOption)); return(1); } - if (mode == Core::ModeButton && buttonGpio <= 0) { - qCCritical(dcApplication()) << "Button mode selected but no valid GPIO passed."; - return(1); + qCWarning(dcApplication()) << "Button mode selected but no valid GPIO passed."; + } + if (!dbusBusType.isEmpty() && dbusBusType != "system" && dbusBusType != "session" && dbusBusType != "none") { + qCCritical(dcApplication()) << "Invalid DBus bus type:" << dbusBusType; + return 1; } qCDebug(dcApplication()) << "====================================="; @@ -251,17 +263,27 @@ int main(int argc, char *argv[]) qCDebug(dcApplication()) << "Platform name:" << platformName; qCDebug(dcApplication()) << "Mode:" << mode; qCDebug(dcApplication()) << "Timeout:" << timeout; - if (mode == Core::ModeButton) + if (mode == Core::ModeButton && buttonGpio > 0) { qCDebug(dcApplication()) << "Button GPIO:" << buttonGpio; + } + if (!dbusBusType.isEmpty() && dbusBusType != "none") { + qCDebug(dcApplication()) << "DBus interface:" << dbusBusType; + } // Start core - Core::instance()->setMode(mode); - Core::instance()->setAdvertisingTimeout(timeout); - Core::instance()->setAdvertiseName(advertiseName); - Core::instance()->setPlatformName(platformName); - Core::instance()->setButtonGpio(buttonGpio); + Core core(&application); + core.setMode(mode); + core.setAdvertisingTimeout(timeout); + core.setAdvertiseName(advertiseName); + core.setPlatformName(platformName); + core.addGPioButton(buttonGpio); + if (dbusBusType == "system") { + core.enableDBusInterface(QDBusConnection::SystemBus); + } else if (dbusBusType == "session") { + core.enableDBusInterface(QDBusConnection::SessionBus); + } - Core::instance()->run(); + core.run(); return application.exec(); } diff --git a/nymea-networkmanager/nymea-networkmanager.pro b/nymea-networkmanager/nymea-networkmanager.pro index fd84155..48db5f0 100644 --- a/nymea-networkmanager/nymea-networkmanager.pro +++ b/nymea-networkmanager/nymea-networkmanager.pro @@ -14,8 +14,8 @@ PKGCONFIG += nymea-networkmanager nymea-gpio HEADERS += \ application.h \ core.h \ - loggingcategories.h \ nymeadservice.h \ + nymeanetworkmanagerdbusservice.h \ pushbuttonagent.h \ @@ -23,8 +23,8 @@ SOURCES += \ main.cpp \ application.cpp \ core.cpp \ - loggingcategories.cpp \ nymeadservice.cpp \ + nymeanetworkmanagerdbusservice.cpp \ pushbuttonagent.cpp \ target.path = /usr/bin diff --git a/nymea-networkmanager/nymeadservice.cpp b/nymea-networkmanager/nymeadservice.cpp index b241fbe..ca9f2a1 100644 --- a/nymea-networkmanager/nymeadservice.cpp +++ b/nymea-networkmanager/nymeadservice.cpp @@ -29,7 +29,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "nymeadservice.h" -#include "loggingcategories.h" + +#include + +Q_LOGGING_CATEGORY(dcNymeaService, "NymeaService") NymeadService::NymeadService(bool pushbuttonEnabled, QObject *parent) : QObject(parent), @@ -65,7 +68,7 @@ bool NymeadService::available() const return m_available; } -void NymeadService::enableBluetooth(const bool &enable) +void NymeadService::enableBluetooth(bool enable) { if (!m_nymeadHardwareBluetoothInterface) { qCWarning(dcNymeaService()) << "Could not enable/disable bluetooth hardware resource. D-Bus interface not available."; diff --git a/nymea-networkmanager/nymeadservice.h b/nymea-networkmanager/nymeadservice.h index ab435a9..cad7840 100644 --- a/nymea-networkmanager/nymeadservice.h +++ b/nymea-networkmanager/nymeadservice.h @@ -46,7 +46,7 @@ public: ~NymeadService(); bool available() const; - void enableBluetooth(const bool &enable); + void enableBluetooth(bool enable); void pushButtonPressed(); private: diff --git a/nymea-networkmanager/nymeanetworkmanagerdbusservice.cpp b/nymea-networkmanager/nymeanetworkmanagerdbusservice.cpp new file mode 100644 index 0000000..b5484a9 --- /dev/null +++ b/nymea-networkmanager/nymeanetworkmanagerdbusservice.cpp @@ -0,0 +1,27 @@ +#include "nymeanetworkmanagerdbusservice.h" + +#include + +Q_LOGGING_CATEGORY(dcDBus, "DBus"); + +NymeaNetworkManagerDBusService::NymeaNetworkManagerDBusService(QDBusConnection::BusType busType, QObject *parent) : QObject(parent), + m_connection(busType == QDBusConnection::SystemBus ? QDBusConnection::systemBus() : QDBusConnection::sessionBus()) +{ + bool status = m_connection.registerService("io.nymea.networkmanager"); + if (!status) { + qCWarning(dcDBus()) << "Failed to register D-Bus service."; + return; + } + status = m_connection.registerObject("/io/nymea/networkmanager", "io.nymea.networkmanager", this, QDBusConnection::ExportScriptableSlots); + if (!status) { + qCWarning(dcDBus()) << "Failed to register D-Bus object."; + return; + } + qCDebug(dcDBus()) << "Registered DBus interface"; +} + +void NymeaNetworkManagerDBusService::enableBluetoothServer() +{ + qCDebug(dcDBus()) << "Enable bluetooth server called"; + emit enableBluetoothServerCalled(); +} diff --git a/nymea-networkmanager/nymeanetworkmanagerdbusservice.h b/nymea-networkmanager/nymeanetworkmanagerdbusservice.h new file mode 100644 index 0000000..9004d34 --- /dev/null +++ b/nymea-networkmanager/nymeanetworkmanagerdbusservice.h @@ -0,0 +1,24 @@ +#ifndef NYMEANETWORKMANAGERDBUSSERVICE_H +#define NYMEANETWORKMANAGERDBUSSERVICE_H + +#include +#include + +class NymeaNetworkManagerDBusService : public QObject +{ + Q_OBJECT +public: + explicit NymeaNetworkManagerDBusService(QDBusConnection::BusType busType, QObject *parent = nullptr); + +public slots: + Q_SCRIPTABLE void enableBluetoothServer(); + +signals: + void enableBluetoothServerCalled(); + +private: + QDBusConnection m_connection; + +}; + +#endif // NYMEANETWORKMANAGERDBUSSERVICE_H diff --git a/nymea-networkmanager/pushbuttonagent.cpp b/nymea-networkmanager/pushbuttonagent.cpp index 994483c..5559c51 100644 --- a/nymea-networkmanager/pushbuttonagent.cpp +++ b/nymea-networkmanager/pushbuttonagent.cpp @@ -29,10 +29,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "pushbuttonagent.h" -#include "loggingcategories.h" #include #include +#include + +Q_DECLARE_LOGGING_CATEGORY(dcNymeaService) PushButtonAgent::PushButtonAgent(QObject *parent) : QObject(parent)