Add a dbus interface to trigger the bluetooth server

Also fixes the button config not working at all
pull/47/head
Michael Zanetti 2021-03-25 23:32:57 +01:00
parent 9951c08304
commit 5a52c00596
14 changed files with 121 additions and 142 deletions

View File

@ -103,6 +103,8 @@ this repository and it will be installed to /etc/nymea-networkmanager.conf with
-m, --mode <MODE> Run the daemon in a specific mode (offline,
once, always, button, start). Default is
"offline".
-b, --dbus-type <DBUSTYPE> If given, a DBus interface will be exposed on
the chosen DBus bus type (session, system)

View File

@ -4,3 +4,4 @@ Timeout=60
AdvertiseName=BT WLAN setup
PlatformName=nymea-box
ButtonGpio=14
DBusBusType=system

View File

@ -29,7 +29,6 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "application.h"
#include "loggingcategories.h"
#include "core.h"
#include <signal.h>
@ -67,7 +66,6 @@ static void catchUnixSignals(const std::vector<int>& quitSignals, const std::vec
qCDebug(dcApplication()) << "=====================================";
s_aboutToShutdown = true;
Core::instance()->destroy();
Application::quit();
};

View File

@ -29,27 +29,11 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "core.h"
#include "loggingcategories.h"
#include "nymeanetworkmanagerdbusservice.h"
#include <QTimer>
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)

View File

@ -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<GpioButton*> 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);
};

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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")

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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 <QDebug>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcApplication)
Q_DECLARE_LOGGING_CATEGORY(dcNymeaService)
#endif // LOGGINGCATEGORIES_H

View File

@ -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();
}

View File

@ -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

View File

@ -29,7 +29,10 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "nymeadservice.h"
#include "loggingcategories.h"
#include <QLoggingCategory>
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.";

View File

@ -46,7 +46,7 @@ public:
~NymeadService();
bool available() const;
void enableBluetooth(const bool &enable);
void enableBluetooth(bool enable);
void pushButtonPressed();
private:

View File

@ -0,0 +1,27 @@
#include "nymeanetworkmanagerdbusservice.h"
#include <QLoggingCategory>
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();
}

View File

@ -0,0 +1,24 @@
#ifndef NYMEANETWORKMANAGERDBUSSERVICE_H
#define NYMEANETWORKMANAGERDBUSSERVICE_H
#include <QObject>
#include <QDBusConnection>
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

View File

@ -29,10 +29,12 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "pushbuttonagent.h"
#include "loggingcategories.h"
#include <QDBusMessage>
#include <QDBusObjectPath>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcNymeaService)
PushButtonAgent::PushButtonAgent(QObject *parent) :
QObject(parent)