refs #520 CDBusServer style/cleanup.

This commit is contained in:
Mathew Sutcliffe
2015-11-29 20:14:31 +00:00
parent 2a980af25b
commit 01d20c53e7
15 changed files with 186 additions and 234 deletions

View File

@@ -33,7 +33,7 @@ namespace BlackCore
case CRuntimeConfig::LocalInDbusServer: case CRuntimeConfig::LocalInDbusServer:
return (new CContextApplication(mode, parent))->registerWithDBus(server); return (new CContextApplication(mode, parent))->registerWithDBus(server);
case CRuntimeConfig::Remote: case CRuntimeConfig::Remote:
return new BlackCore::CContextApplicationProxy(BlackMisc::CDBusServer::ServiceName(), connection, mode, parent); return new BlackCore::CContextApplicationProxy(BlackMisc::CDBusServer::coreServiceName(), connection, mode, parent);
case CRuntimeConfig::NotUsed: case CRuntimeConfig::NotUsed:
default: default:
return new CContextApplicationEmpty(parent); return new CContextApplicationEmpty(parent);

View File

@@ -23,7 +23,7 @@ namespace BlackCore
case CRuntimeConfig::LocalInDbusServer: case CRuntimeConfig::LocalInDbusServer:
return (new CContextAudio(mode, runtime))->registerWithDBus(server); return (new CContextAudio(mode, runtime))->registerWithDBus(server);
case CRuntimeConfig::Remote: case CRuntimeConfig::Remote:
return new CContextAudioProxy(BlackMisc::CDBusServer::ServiceName(), conn, mode, runtime); return new CContextAudioProxy(BlackMisc::CDBusServer::coreServiceName(), conn, mode, runtime);
default: default:
return new CContextAudioEmpty(runtime); // audio not mandatory return new CContextAudioEmpty(runtime); // audio not mandatory
} }

View File

@@ -23,7 +23,7 @@ namespace BlackCore
case CRuntimeConfig::LocalInDbusServer: case CRuntimeConfig::LocalInDbusServer:
return (new CContextNetwork(mode, runtime))->registerWithDBus(server); return (new CContextNetwork(mode, runtime))->registerWithDBus(server);
case CRuntimeConfig::Remote: case CRuntimeConfig::Remote:
return new CContextNetworkProxy(BlackMisc::CDBusServer::ServiceName(), connection, mode, runtime); return new CContextNetworkProxy(BlackMisc::CDBusServer::coreServiceName(), connection, mode, runtime);
case CRuntimeConfig::NotUsed: case CRuntimeConfig::NotUsed:
default: default:
return new CContextNetworkEmpty(runtime); return new CContextNetworkEmpty(runtime);

View File

@@ -22,7 +22,7 @@ namespace BlackCore
case CRuntimeConfig::LocalInDbusServer: case CRuntimeConfig::LocalInDbusServer:
return (new CContextOwnAircraft(mode, parent))->registerWithDBus(server); return (new CContextOwnAircraft(mode, parent))->registerWithDBus(server);
case CRuntimeConfig::Remote: case CRuntimeConfig::Remote:
return new CContextOwnAircraftProxy(BlackMisc::CDBusServer::ServiceName(), conn, mode, parent); return new CContextOwnAircraftProxy(BlackMisc::CDBusServer::coreServiceName(), conn, mode, parent);
case CRuntimeConfig::NotUsed: case CRuntimeConfig::NotUsed:
default: default:
return new CContextOwnAircraftEmpty(parent); return new CContextOwnAircraftEmpty(parent);

View File

@@ -212,7 +212,7 @@ namespace BlackCore
disconnect(this); disconnect(this);
// unregister all from DBus // unregister all from DBus
if (this->m_dbusServer) { this->m_dbusServer->unregisterAllObjects(); } if (this->m_dbusServer) { this->m_dbusServer->removeAllObjects(); }
// handle contexts // handle contexts
if (this->getIContextSimulator()) if (this->getIContextSimulator())
@@ -272,11 +272,11 @@ namespace BlackCore
void CRuntime::initDBusConnection(const QString &address) void CRuntime::initDBusConnection(const QString &address)
{ {
if (this->m_initDBusConnection) { return; } if (this->m_initDBusConnection) { return; }
if (address.isEmpty() || address == CDBusServer::sessionDBusServer()) if (address.isEmpty() || address == CDBusServer::sessionBusAddress())
{ {
this->m_dbusConnection = QDBusConnection::sessionBus(); this->m_dbusConnection = QDBusConnection::sessionBus();
} }
else if (address == CDBusServer::systemDBusServer()) else if (address == CDBusServer::systemBusAddress())
{ {
this->m_dbusConnection = QDBusConnection::sessionBus(); this->m_dbusConnection = QDBusConnection::sessionBus();
} }

View File

@@ -42,7 +42,7 @@ namespace BlackCore
case CRuntimeConfig::LocalInDbusServer: case CRuntimeConfig::LocalInDbusServer:
return (new CContextSimulator(mode, parent))->registerWithDBus(server); return (new CContextSimulator(mode, parent))->registerWithDBus(server);
case CRuntimeConfig::Remote: case CRuntimeConfig::Remote:
return new CContextSimulatorProxy(BlackMisc::CDBusServer::ServiceName(), conn, mode, parent); return new CContextSimulatorProxy(BlackMisc::CDBusServer::coreServiceName(), conn, mode, parent);
case CRuntimeConfig::NotUsed: case CRuntimeConfig::NotUsed:
default: default:
return new CContextSimulatorEmpty(parent); return new CContextSimulatorEmpty(parent);

View File

@@ -17,44 +17,35 @@ using namespace BlackMisc::Network;
namespace BlackMisc namespace BlackMisc
{ {
/*
* Constructor
* Remark, without the default "unix:tmpdir=/tmp" any refereal to address crashes
* see http://download.froglogic.com/public/qt5-squishcoco-report/QtBase/source_241_preprocessed.html
* DBus config: http://dbus.freedesktop.org/doc/dbus-daemon.1.html
*/
CDBusServer::CDBusServer(const QString &service, const QString &address, QObject *parent) : QObject(parent) CDBusServer::CDBusServer(const QString &service, const QString &address, QObject *parent) : QObject(parent)
{ {
ServerMode m = CDBusServer::addressToDBusMode(address); m_serverMode = modeOfAddress(address);
switch (m) switch (m_serverMode)
{ {
case SERVERMODE_SESSIONBUS: case SERVERMODE_SESSIONBUS:
{ {
// we use a session bus connection instead of a real P2P connection QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
this->m_serverMode = CDBusServer::SERVERMODE_SESSIONBUS;
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, ServiceName());
if (! connection.isConnected()) if (! connection.isConnected())
{ {
launchDbusDaemon(); launchDBusDaemon();
connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, ServiceName()); connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
} }
if (! connection.registerService(service)) if (! connection.registerService(service))
{ {
// registration fails can either mean something wrong with DBus or service already exists // registration fails can either mean something wrong with DBus or service already exists
CLogMessage(this).warning("DBus registration: %1") << connection.lastError().message(); CLogMessage(this).warning("DBus registration: %1") << connection.lastError().message();
CLogMessage(this).warning("Cannot register DBus service, server started? dbus-daemon.exe --session --address=tcp:host=192.168.0.133,port=45000"); CLogMessage(this).warning("Cannot register DBus service, check server running: dbus-daemon.exe --session --address=tcp:host=192.168.0.133,port=45000");
} }
} }
break; break;
case SERVERMODE_SYSTEMBUS: case SERVERMODE_SYSTEMBUS:
{ {
// we use a system bus connection instead of a real P2P connection
this->m_serverMode = CDBusServer::SERVERMODE_SYSTEMBUS;
QDBusConnection connection = QDBusConnection::systemBus(); QDBusConnection connection = QDBusConnection::systemBus();
if (!connection.isConnected()) if (!connection.isConnected())
{ {
launchDbusDaemon(); launchDBusDaemon();
connection = QDBusConnection::systemBus(); connection = QDBusConnection::systemBus();
} }
@@ -62,46 +53,42 @@ namespace BlackMisc
{ {
// registration fails can either mean something wrong with DBus or service already exists // registration fails can either mean something wrong with DBus or service already exists
CLogMessage(this).warning("DBus registration: %1") << connection.lastError().message(); CLogMessage(this).warning("DBus registration: %1") << connection.lastError().message();
CLogMessage(this).warning("Cannot register DBus service, server started? dbus-daemon.exe --session --address=tcp:host=192.168.0.133,port=45000"); CLogMessage(this).warning("Cannot register DBus service, check server running: dbus-daemon.exe --system --address=tcp:host=192.168.0.133,port=45000");
} }
} }
break; break;
case SERVERMODE_P2P: case SERVERMODE_P2P:
default: default:
{ {
QString dbusAddress(CDBusServer::isQtDBusAddress(address) ? address : "tcp:host=127.0.0.1,port=45000"); QString dbusAddress = isQtDBusAddress(address) ? address : "tcp:host=127.0.0.1,port=45000";
dbusAddress = dbusAddress.toLower().trimmed().replace(' ', ""); dbusAddress = dbusAddress.toLower().trimmed().replace(' ', "");
if (!dbusAddress.contains("bind=")) { dbusAddress = dbusAddress.append(",bind=*"); } if (! dbusAddress.contains("bind=")) { dbusAddress = dbusAddress.append(",bind=*"); } // bind to all network interfaces
this->m_serverMode = CDBusServer::SERVERMODE_P2P;
this->m_busServer.reset( m_busServer.reset(new QDBusServer(dbusAddress, parent));
new QDBusServer(
dbusAddress, // "unix:tmpdir=/tmp"
parent)
);
m_busServer->setAnonymousAuthenticationAllowed(true); m_busServer->setAnonymousAuthenticationAllowed(true);
// Note: P2P has no service name // Note: P2P has no service name
if (!m_busServer->isConnected()) if (m_busServer->isConnected())
{ {
CLogMessage(this).warning("DBus P2P connection failed: %1") << this->lastQDBusServerError().message(); CLogMessage(this).debug() << "Server listening on address:" << m_busServer->address();
} }
else else
{ {
CLogMessage(this).debug() << "Server listening on address: " << m_busServer->address(); CLogMessage(this).warning("DBus P2P connection failed: %1") << lastQDBusServerError().message();
} }
connect(m_busServer.data(), &QDBusServer::newConnection, this, &CDBusServer::ps_registerObjectsWithP2PConnection); connect(m_busServer.data(), &QDBusServer::newConnection, this, &CDBusServer::ps_registerObjectsWithP2PConnection);
} }
break; break;
} // switch }
} }
const QString &CDBusServer::ServiceName() const QString &CDBusServer::coreServiceName()
{ {
static const QString sn(SWIFT_SERVICENAME); static const QString sn = SWIFT_SERVICENAME;
return sn; return sn;
} }
void CDBusServer::launchDbusDaemon() void CDBusServer::launchDBusDaemon()
{ {
const QString program = QStringLiteral("dbus-daemon"); const QString program = QStringLiteral("dbus-daemon");
const QStringList arguments = { QStringLiteral("--config-file=../share/dbus-1/session.conf") }; const QStringList arguments = { QStringLiteral("--config-file=../share/dbus-1/session.conf") };
@@ -111,86 +98,75 @@ namespace BlackMisc
bool CDBusServer::isP2PAddress(const QString &address) bool CDBusServer::isP2PAddress(const QString &address)
{ {
return CDBusServer::addressToDBusMode(address) == SERVERMODE_P2P; return modeOfAddress(address) == SERVERMODE_P2P;
} }
bool CDBusServer::splitDBusAddressIntoHostAndPort(const QString &dbusAddress, QString &host, int &port) bool CDBusServer::dBusAddressToHostAndPort(QString address, QString &host, int &port)
{ {
bool ok = false; address = address.trimmed().toLower().replace(' ', "");
QString dbus(dbusAddress.trimmed().toLower().replace(' ', "")); if (address.contains("host=") || address.contains("port="))
if (dbus.contains("host=") || dbus.contains("port="))
{ {
// "tcp:host=foo.com,port=123" // "tcp:host=foo.com,port=123"
QStringList parts(dbus.split(',')); QStringList parts(address.split(','));
for (const QString &p : parts) for (const QString &part : parts)
{ {
if (p.contains("host=")) if (part.startsWith("host="))
{ {
host = p.mid(p.lastIndexOf("=") + 1).trimmed(); host = part.mid(part.lastIndexOf("=") + 1).trimmed();
} }
else if (p.contains("port=")) else if (part.startsWith("port="))
{ {
bool ok; bool ok;
port = p.mid(p.lastIndexOf("=") + 1).trimmed().toInt(&ok); port = part.mid(part.lastIndexOf("=") + 1).trimmed().toInt(&ok);
if (! ok) { port = -1; } if (! ok) { port = -1; }
} }
} }
if (port < 0) { port = 45000; } if (port < 0) { port = 45000; }
if (host.isEmpty()) { host = "127.0.0.1"; } if (host.isEmpty()) { host = "127.0.0.1"; }
ok = true; return true;
} }
else
if (!ok)
{ {
host = ""; host = "";
port = -1; port = -1;
return false;
} }
return ok;
} }
bool CDBusServer::isQtDBusAddress(const QString &address) bool CDBusServer::isQtDBusAddress(const QString &address)
{ {
return return address.startsWith("tcp:") || address.startsWith("unix:");
(address.contains("tcp:") ||
address.contains("unix:")
);
} }
bool CDBusServer::isSessionOrSystemAddress(const QString &address) bool CDBusServer::isSessionOrSystemAddress(const QString &address)
{ {
return address == sessionDBusServer() || address == systemDBusServer(); return address == sessionBusAddress() || address == systemBusAddress();
} }
const QString CDBusServer::getClassInfo(QObject *object) QString CDBusServer::getDBusInterfaceFromClassInfo(QObject *object)
{ {
if (!object) return ""; if (! object) { return ""; }
const QMetaObject *mo = object->metaObject(); const QMetaObject *mo = object->metaObject();
if (mo->classInfoCount() < 1) return "";
for (int i = 0; i < mo->classInfoCount(); i++) for (int i = 0; i < mo->classInfoCount(); i++)
{ {
QMetaClassInfo ci = mo->classInfo(i); QMetaClassInfo ci = mo->classInfo(i);
QString name(ci.name()); if (ci.name() == "D-Bus Interface") { return QString(ci.value()); }
if (name == "D-Bus Interface") { return QString(ci.value()); }
} }
return ""; return "";
} }
bool CDBusServer::ps_registerObjectsWithP2PConnection(const QDBusConnection &connection) bool CDBusServer::ps_registerObjectsWithP2PConnection(QDBusConnection connection)
{ {
Q_ASSERT(!this->m_objects.isEmpty()); Q_ASSERT(! m_objects.isEmpty());
QDBusConnection newConnection(connection); // copy, because object will be registered on this connection m_connections.insert(connection.name(), connection);
// insert or replace connection CLogMessage(this).debug() << "New Connection from:" << connection.name();
m_DBusConnections.insert(newConnection.name(), newConnection);
bool success = true; bool success = true;
CLogMessage(this).debug() << "New Connection from: " << newConnection.name(); for (auto i = m_objects.begin(); i != m_objects.end(); ++i)
QMap<QString, QObject *>::ConstIterator i = m_objects.begin();
while (i != m_objects.end())
{ {
CLogMessage(this).debug() << "Adding " << i.key() << CDBusServer::getClassInfo(i.value()) << "to the new connection."; CLogMessage(this).debug() << "Adding" << i.key() << getDBusInterfaceFromClassInfo(i.value()) << "to the new connection.";
bool ok = newConnection.registerObject(i.key(), i.value(), CDBusServer::RegisterOptions()); bool ok = connection.registerObject(i.key(), i.value(), registerOptions());
Q_ASSERT_X(ok, "CDBusServer::newConnection", "Registration failed"); Q_ASSERT_X(ok, "CDBusServer::newConnection", "Registration failed");
if (! ok) { success = false; } if (! ok) { success = false; }
++i;
} }
return success; return success;
} }
@@ -198,86 +174,81 @@ namespace BlackMisc
void CDBusServer::addObject(const QString &path, QObject *object) void CDBusServer::addObject(const QString &path, QObject *object)
{ {
if (! object) { return; } if (! object) { return; }
m_objects.insert(path, object); // For P2P: registered when P2P connection is established m_objects.insert(path, object); // will be registered when P2P connection is established
// P2P switch (m_serverMode)
if (this->m_serverMode == CDBusServer::SERVERMODE_P2P)
{ {
return; case SERVERMODE_SESSIONBUS:
}
bool success = false;
if (this->m_serverMode == CDBusServer::SERVERMODE_SESSIONBUS)
{ {
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, ServiceName()); QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
success = connection.registerObject(path, object, CDBusServer::RegisterOptions()); if (connection.registerObject(path, object, registerOptions()))
if (success)
{ {
CLogMessage(this).debug() << "Adding " << path << CDBusServer::getClassInfo(object) << " to session bus."; CLogMessage(this).debug() << "Adding" << path << getDBusInterfaceFromClassInfo(object) << "to session bus.";
} }
else else
{ {
CLogMessage(this).error("Error, no success with session bus registration"); CLogMessage(this).error("Error, no success with session bus registration");
} }
} }
else if (this->m_serverMode == CDBusServer::SERVERMODE_SYSTEMBUS) break;
case SERVERMODE_SYSTEMBUS:
{ {
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, ServiceName()); QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, coreServiceName());
success = connection.registerObject(path, object, CDBusServer::RegisterOptions()); if (connection.registerObject(path, object, registerOptions()))
if (success)
{ {
CLogMessage(this).debug() << "Adding " << path << CDBusServer::getClassInfo(object) << " to system bus."; CLogMessage(this).debug() << "Adding" << path << getDBusInterfaceFromClassInfo(object) << "to system bus.";
} }
else else
{ {
CLogMessage(this).error("Error, no success with system bus registration"); CLogMessage(this).error("Error, no success with system bus registration");
} }
} }
else break;
{ case SERVERMODE_P2P:
break;
default:
Q_ASSERT_X(false, "CDBusServer::addObject", "Wrong server mode"); Q_ASSERT_X(false, "CDBusServer::addObject", "Wrong server mode");
} }
} }
QDBusError CDBusServer::lastQDBusServerError() const QDBusError CDBusServer::lastQDBusServerError() const
{ {
if (!hasQDBusServer()) { return QDBusError(); } if (! hasQDBusServer()) { return {}; }
return this->m_busServer->lastError(); return m_busServer->lastError();
} }
const QDBusServer *CDBusServer::qDBusServer() const const QDBusServer *CDBusServer::qDBusServer() const
{ {
return this->m_busServer.data(); return m_busServer.data();
} }
bool CDBusServer::hasQDBusServer() const bool CDBusServer::hasQDBusServer() const
{ {
return !this->m_busServer.isNull(); return ! m_busServer.isNull();
} }
void CDBusServer::unregisterAllObjects() void CDBusServer::removeAllObjects()
{ {
if (this->m_objects.isEmpty()) return; for (const QString &path : m_objects.keys())
foreach(QString path, this->m_objects.keys())
{ {
switch (this->m_serverMode) switch (m_serverMode)
{ {
case CDBusServer::SERVERMODE_SESSIONBUS: case SERVERMODE_SESSIONBUS:
QDBusConnection::sessionBus().unregisterObject(path); QDBusConnection::sessionBus().unregisterObject(path);
break; break;
case CDBusServer::SERVERMODE_SYSTEMBUS: case SERVERMODE_SYSTEMBUS:
QDBusConnection::systemBus().unregisterObject(path); QDBusConnection::systemBus().unregisterObject(path);
break; break;
case CDBusServer::SERVERMODE_P2P: case SERVERMODE_P2P:
{ {
foreach(QDBusConnection connection, this->m_DBusConnections) for(QDBusConnection connection : m_connections)
{ {
connection.unregisterObject(path); connection.unregisterObject(path);
} }
break; break;
} }
} }
} // all paths }
} }
const QDBusConnection &CDBusServer::defaultConnection() const QDBusConnection &CDBusServer::defaultConnection()
@@ -286,15 +257,15 @@ namespace BlackMisc
return defaultConnection; return defaultConnection;
} }
const QString &CDBusServer::sessionDBusServer() const QString &CDBusServer::sessionBusAddress()
{ {
static QString session("session"); static QString session = "session";
return session; return session;
} }
const QString &CDBusServer::systemDBusServer() const QString &CDBusServer::systemBusAddress()
{ {
static QString system("system"); static QString system = "system";
return system; return system;
} }
@@ -303,8 +274,7 @@ namespace BlackMisc
QString h = host.isEmpty() ? "127.0.0.1" : host.trimmed(); QString h = host.isEmpty() ? "127.0.0.1" : host.trimmed();
QString p = port; QString p = port;
// can handle host and port separately or combined // can handle host and port separately or combined, e.g. "myhost:1234"
// such as "myHost::1234"
if (port.isEmpty()) if (port.isEmpty())
{ {
if (h.contains(":")) if (h.contains(":"))
@@ -322,47 +292,46 @@ namespace BlackMisc
} }
// todo: Replace assert with input validation // todo: Replace assert with input validation
Q_ASSERT_X(CNetworkUtils::isValidIPv4Address(p), "p2pAdress", "Wrong IP in String"); Q_ASSERT_X(CNetworkUtils::isValidIPv4Address(p), "CDBusServer::p2pAddress", "Wrong IP in String");
QString p2p = QString("tcp:host=%1,port=%2").arg(h).arg(p); return QString("tcp:host=%1,port=%2").arg(h).arg(p);
return p2p;
} }
QString CDBusServer::fixAddressToDBusAddress(const QString &address) QString CDBusServer::normalizeAddress(const QString &address)
{ {
if (address.isEmpty() || address == sessionDBusServer() || address == systemDBusServer()) { return address; } if (address.isEmpty() || address == sessionBusAddress() || address == systemBusAddress()) { return address; }
if (address.startsWith("tcp:") || address.startsWith("unix:")) return address; if (isQtDBusAddress(address)) { return address; }
return p2pAddress(address); return p2pAddress(address);
} }
CDBusServer::ServerMode CDBusServer::addressToDBusMode(const QString &address) CDBusServer::ServerMode CDBusServer::modeOfAddress(QString address)
{ {
QString a = address.toLower(); address = address.toLower();
if (a == CDBusServer::systemDBusServer()) { return SERVERMODE_SYSTEMBUS; } if (address == systemBusAddress()) { return SERVERMODE_SYSTEMBUS; }
else if (a == CDBusServer::sessionDBusServer()) { return SERVERMODE_SESSIONBUS; } else if (address == sessionBusAddress()) { return SERVERMODE_SESSIONBUS; }
else { return SERVERMODE_P2P; } else { return SERVERMODE_P2P; }
} }
bool CDBusServer::isDBusAvailable(const QString &address, int port, int timeoutMs) bool CDBusServer::isDBusAvailable(const QString &address, int port, int timeoutMs)
{ {
QString m; QString unused;
return CNetworkUtils::canConnect(address, port, m, timeoutMs); return CNetworkUtils::canConnect(address, port, unused, timeoutMs);
} }
bool CDBusServer::isDBusAvailable(const QString &address, int port, QString &message, int timeoutMs) bool CDBusServer::isDBusAvailable(const QString &address, int port, QString &o_message, int timeoutMs)
{ {
return CNetworkUtils::canConnect(address, port, message, timeoutMs); return CNetworkUtils::canConnect(address, port, o_message, timeoutMs);
} }
bool CDBusServer::isDBusAvailable(const QString &dbusAddress, QString &message, int timeoutMs) bool CDBusServer::isDBusAvailable(const QString &dbusAddress, QString &o_message, int timeoutMs)
{ {
if (dbusAddress.isEmpty()) { message = "no address"; return false; } if (dbusAddress.isEmpty()) { o_message = "no address"; return false; }
if (isP2PAddress(dbusAddress)) if (isP2PAddress(dbusAddress))
{ {
QString host; QString host;
int port = -1; int port = -1;
if (splitDBusAddressIntoHostAndPort(dbusAddress, host, port)) if (dBusAddressToHostAndPort(dbusAddress, host, port))
{ {
return isDBusAvailable(host, port, message, timeoutMs); return isDBusAvailable(host, port, o_message, timeoutMs);
} }
else else
{ {
@@ -371,26 +340,20 @@ namespace BlackMisc
} }
else else
{ {
QDBusConnection connection( QDBusConnection connection(dbusAddress == systemBusAddress() ? QDBusConnection::systemBus() : QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName()));
(dbusAddress == systemDBusServer()) ?
QDBusConnection::systemBus() :
QDBusConnection::connectToBus(QDBusConnection::SessionBus, ServiceName())
);
bool success = connection.isConnected();
// further checks would need to go here // todo: further checks would need to go here
// failing session bus not detected yet // failing session bus not detected yet
message = connection.lastError().message(); o_message = connection.lastError().message();
connection.disconnectFromBus(ServiceName()); return connection.isConnected();
return success;
} }
} }
bool CDBusServer::isDBusAvailable(const QString &dbusAddress, int timeoutMs) bool CDBusServer::isDBusAvailable(const QString &dbusAddress, int timeoutMs)
{ {
QString m; QString unused;
return isDBusAvailable(dbusAddress, m, timeoutMs); return isDBusAvailable(dbusAddress, unused, timeoutMs);
} }
} // namespace } // namespace

View File

@@ -13,7 +13,7 @@
#define BLACKMISC_DBUSSERVER_H #define BLACKMISC_DBUSSERVER_H
#include "blackmiscexport.h" #include "blackmiscexport.h"
#include "blackmisc/valueobject.h" // for qHash overload, include before Qt stuff due GCC issue #include "blackmisc/valueobject.h"
#include <QObject> #include <QObject>
#include <QtDBus/QDBusServer> #include <QtDBus/QDBusServer>
#include <QtDBus/QDBusError> #include <QtDBus/QDBusError>
@@ -31,7 +31,7 @@ namespace BlackMisc
* Custom DBusServer * Custom DBusServer
* \details This class implements a custom DBusServer for DBus peer connections, but can also be used * \details This class implements a custom DBusServer for DBus peer connections, but can also be used
* with session or system bus. For session/system bus this class represents no real server, * with session or system bus. For session/system bus this class represents no real server,
* but more a wrapper for \sa QDBusConnection and the registered objects * but more a wrapper for QDBusConnection and object registration.
*/ */
class BLACKMISC_EXPORT CDBusServer : public QObject class BLACKMISC_EXPORT CDBusServer : public QObject
{ {
@@ -39,10 +39,10 @@ namespace BlackMisc
Q_CLASSINFO("D-Bus Interface", SWIFT_SERVICENAME) Q_CLASSINFO("D-Bus Interface", SWIFT_SERVICENAME)
public: public:
//! Service name of DBus server //! Default service name
static const QString &ServiceName(); static const QString &coreServiceName();
//! Server mode, normally P2P, but can be changed for debugging / testing //! Server mode
enum ServerMode enum ServerMode
{ {
SERVERMODE_P2P, SERVERMODE_P2P,
@@ -50,95 +50,84 @@ namespace BlackMisc
SERVERMODE_SYSTEMBUS SERVERMODE_SYSTEMBUS
}; };
//! Construct a server for the BlackCore runtime //! Construct a server for the core service
//! \remarks We are using address and not ServerMode, as on some systems we need to pass in some specific configuration string CDBusServer(const QString &address, QObject *parent = nullptr) : CDBusServer(coreServiceName(), address, parent) {}
//! \sa QDBusServer
CDBusServer(const QString &address, QObject *parent = nullptr) : CDBusServer(CDBusServer::ServiceName(), address, parent) {}
//! Construct a server for some arbitrary service //! Construct a server for some arbitrary service
CDBusServer(const QString &service, const QString &address, QObject *parent = nullptr); CDBusServer(const QString &service, const QString &address, QObject *parent = nullptr);
//!! Adds a QObject to be exposed to DBus //! Add a QObject to be exposed via DBus
void addObject(const QString &name, QObject *object); void addObject(const QString &name, QObject *object);
//! Last error //! Last error
QDBusError lastQDBusServerError() const; QDBusError lastQDBusServerError() const;
//! DBus server (if avaialable) //! DBus server (if using P2P)
const QDBusServer *qDBusServer() const; const QDBusServer *qDBusServer() const;
//! With (P2P) DBus server //! True if using P2P
bool hasQDBusServer() const; bool hasQDBusServer() const;
//! Unregister all objects //! Remove all objects added with addObject
void unregisterAllObjects(); void removeAllObjects();
//! Default connection //! Default connection
static const QDBusConnection &defaultConnection(); static const QDBusConnection &defaultConnection();
//! Denotes a session DBus server //! Address denoting a session bus server
static const QString &sessionDBusServer(); static const QString &sessionBusAddress();
//! Denotes a session DBus server //! Address denoting a system bus server
static const QString &systemDBusServer(); static const QString &systemBusAddress();
//! Denotes a P2P DBus server, e.g. "tcp:host=192.168.3.3,port=45000" //! Address denoting a P2P server at the given host and port.
//! \remarks it is valid to pass only one string as host:port //! \remarks Port number may be embedding in the host string after a colon.
static QString p2pAddress(const QString &host = "127.0.0.1", const QString &port = ""); static QString p2pAddress(const QString &host = "127.0.0.1", const QString &port = "");
//! Turn something like 127.0.0.1:45000 into "tcp:host=127.0.0.1,port=45000" //! Turn something like 127.0.0.1:45000 into "tcp:host=127.0.0.1,port=45000"
static QString fixAddressToDBusAddress(const QString &address); static QString normalizeAddress(const QString &address);
//! address to DBus server mode //! Return the server mode of the given address
static ServerMode addressToDBusMode(const QString &address); static ServerMode modeOfAddress(QString address);
//! Qt DBus address, e.g. "unix:tmpdir=/tmp", "tcp:host=127.0.0.1,port=45000" //! True if a valid Qt DBus address, e.g. "unix:tmpdir=/tmp", "tcp:host=127.0.0.1,port=45000"
static bool isQtDBusAddress(const QString &address); static bool isQtDBusAddress(const QString &address);
//! Session or system DBus address //! True if address is session or system bus address
static bool isSessionOrSystemAddress(const QString &address); static bool isSessionOrSystemAddress(const QString &address);
//! Check if address means a real server with P2P connection //! False if address is session or system bus address
static bool isP2PAddress(const QString &address); static bool isP2PAddress(const QString &address);
//! Split DBus address into host and port //! Extract host and port from a DBus address
static bool splitDBusAddressIntoHostAndPort(const QString &dbusAddress, QString &host, int &port); static bool dBusAddressToHostAndPort(QString dbusAddress, QString &o_host, int &o_port);
//! Is DBus available? //! Is there a DBus server running at the given address?
static bool isDBusAvailable(const QString &address, int port, int timeoutMs = 1500); //! @{
static bool isDBusAvailable(const QString &host, int port, int timeoutMs = 1500);
//! Is DBus available? static bool isDBusAvailable(const QString &host, int port, QString &o_message, int timeoutMs = 1500);
static bool isDBusAvailable(const QString &address, int port, QString &message, int timeoutMs = 1500); static bool isDBusAvailable(const QString &dbusAddress, QString &o_message, int timeoutMs = 1500);
//! Is DBus available?
static bool isDBusAvailable(const QString &dbusAddress, QString &message, int timeoutMs = 1500);
//! Is DBus available?
static bool isDBusAvailable(const QString &dbusAddress, int timeoutMs = 1500); static bool isDBusAvailable(const QString &dbusAddress, int timeoutMs = 1500);
//! @}
private: private:
ServerMode m_serverMode = SERVERMODE_P2P; ServerMode m_serverMode = SERVERMODE_P2P;
QScopedPointer<QDBusServer> m_busServer; //!< QDBusServer implementation QScopedPointer<QDBusServer> m_busServer;
QMap<QString, QObject *> m_objects; //!< Mapping of all exposed objects, for P2P registration when connection establishes, also to later unregister objects QMap<QString, QObject *> m_objects;
QMap<QString, QDBusConnection> m_DBusConnections; //!< Mapping of all DBusConnection objects QMap<QString, QDBusConnection> m_connections;
//! Manually launch our shipped dbus daemon void launchDBusDaemon();
void launchDbusDaemon(); static QString getDBusInterfaceFromClassInfo(QObject *object);
//! Get the class info
static const QString getClassInfo(QObject *object);
//! Register options with connection //! Register options with connection
static const QDBusConnection::RegisterOptions &RegisterOptions() static QDBusConnection::RegisterOptions registerOptions()
{ {
static QDBusConnection::RegisterOptions opt = QDBusConnection::ExportAdaptors | QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllSlots; return QDBusConnection::ExportAdaptors | QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllSlots;
return opt;
} }
private slots: private slots:
//! Called when a new DBus client has connected in P2P mode //! Called when a new DBus client has connected in P2P mode
bool ps_registerObjectsWithP2PConnection(const QDBusConnection &connection); bool ps_registerObjectsWithP2PConnection(QDBusConnection connection);
}; };
} }

View File

@@ -354,11 +354,11 @@ namespace BlackSimPlugin
QDBusConnection CSimulatorXPlane::connectionFromString(const QString &str) QDBusConnection CSimulatorXPlane::connectionFromString(const QString &str)
{ {
if (str == BlackMisc::CDBusServer::sessionDBusServer()) if (str == BlackMisc::CDBusServer::sessionBusAddress())
{ {
return QDBusConnection::sessionBus(); return QDBusConnection::sessionBus();
} }
else if (str == BlackMisc::CDBusServer::systemDBusServer()) else if (str == BlackMisc::CDBusServer::systemBusAddress())
{ {
return QDBusConnection::systemBus(); return QDBusConnection::systemBus();
} }

View File

@@ -30,8 +30,8 @@ namespace BlackSimPlugin
{ {
ui->setupUi(this); ui->setupUi(this);
ui->cp_XBusServer->addItem(BlackMisc::CDBusServer::sessionDBusServer()); ui->cp_XBusServer->addItem(BlackMisc::CDBusServer::sessionBusAddress());
ui->cp_XBusServer->addItem(BlackMisc::CDBusServer::systemDBusServer()); ui->cp_XBusServer->addItem(BlackMisc::CDBusServer::systemBusAddress());
connect(ui->bb_OkCancel, &QDialogButtonBox::accepted, this, &CSimulatorXPlaneConfigWindow::ps_storeSettings); connect(ui->bb_OkCancel, &QDialogButtonBox::accepted, this, &CSimulatorXPlaneConfigWindow::ps_storeSettings);
connect(ui->bb_OkCancel, &QDialogButtonBox::accepted, this, &CSimulatorXPlaneConfigWindow::close); connect(ui->bb_OkCancel, &QDialogButtonBox::accepted, this, &CSimulatorXPlaneConfigWindow::close);

View File

@@ -58,7 +58,7 @@ CommandLineParseResult parseCommandLine(QCommandLineParser &parser, CSwiftCore::
if (parser.isSet(helpOption)) { return CommandLineHelpRequested; } if (parser.isSet(helpOption)) { return CommandLineHelpRequested; }
if (parser.isSet(versionOption)) { return CommandLineVersionRequested; } if (parser.isSet(versionOption)) { return CommandLineVersionRequested; }
setup->m_dbusAddress = CDBusServer::sessionDBusServer(); // default setup->m_dbusAddress = CDBusServer::sessionBusAddress(); // default
if (parser.isSet("dbus")) if (parser.isSet("dbus"))
{ {
QString v(parser.value("dbus").trimmed().toLower()); QString v(parser.value("dbus").trimmed().toLower());
@@ -68,7 +68,7 @@ CommandLineParseResult parseCommandLine(QCommandLineParser &parser, CSwiftCore::
} }
else if (v.contains("sys")) else if (v.contains("sys"))
{ {
setup->m_dbusAddress = CDBusServer::systemDBusServer(); // default setup->m_dbusAddress = CDBusServer::systemBusAddress(); // default
} }
} }

View File

@@ -60,11 +60,11 @@ void CSwiftCore::initStyleSheet()
void CSwiftCore::initDBusMode(const CSwiftCore::SetupInfo &setup) void CSwiftCore::initDBusMode(const CSwiftCore::SetupInfo &setup)
{ {
if (setup.m_dbusAddress.startsWith(CDBusServer::sessionDBusServer())) if (setup.m_dbusAddress.startsWith(CDBusServer::sessionBusAddress()))
{ {
this->ui->rb_SessionBus->setChecked(true); this->ui->rb_SessionBus->setChecked(true);
} }
else if (setup.m_dbusAddress.startsWith(CDBusServer::systemDBusServer())) else if (setup.m_dbusAddress.startsWith(CDBusServer::systemBusAddress()))
{ {
this->ui->rb_SystemBus->setChecked(true); this->ui->rb_SystemBus->setChecked(true);
} }
@@ -167,9 +167,9 @@ void CSwiftCore::stopCore()
QString CSwiftCore::getDBusAddress() const QString CSwiftCore::getDBusAddress() const
{ {
if (ui->rb_SessionBus->isChecked()) { return CDBusServer::sessionDBusServer(); } if (ui->rb_SessionBus->isChecked()) { return CDBusServer::sessionBusAddress(); }
if (ui->rb_SystemBus->isChecked()) { return CDBusServer::systemDBusServer(); } if (ui->rb_SystemBus->isChecked()) { return CDBusServer::systemBusAddress(); }
if (ui->rb_P2PBus->isChecked()) { return CDBusServer::fixAddressToDBusAddress(ui->le_P2PAddress->text()); } if (ui->rb_P2PBus->isChecked()) { return CDBusServer::normalizeAddress(ui->le_P2PAddress->text()); }
Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong DBus address"); Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong DBus address");
return ""; return "";

View File

@@ -80,7 +80,7 @@ CommandLineParseResult parseCommandLine(QCommandLineParser &parser,
if (parser.isSet(dBusOption)) if (parser.isSet(dBusOption))
{ {
QString v(parser.value(dBusOption).trimmed()); QString v(parser.value(dBusOption).trimmed());
dBusAddress = CDBusServer::fixAddressToDBusAddress(v); dBusAddress = CDBusServer::normalizeAddress(v);
if (!CDBusServer::isDBusAvailable(dBusAddress)) if (!CDBusServer::isDBusAvailable(dBusAddress))
{ {
errorMessage = "DBus server at " + dBusAddress + " can not be reached"; errorMessage = "DBus server at " + dBusAddress + " can not be reached";

View File

@@ -83,9 +83,9 @@ GuiModes::CoreMode CSwiftLauncher::getCoreMode() const
QString CSwiftLauncher::getDBusAddress() const QString CSwiftLauncher::getDBusAddress() const
{ {
if (this->ui->rb_DBusSession->isChecked()) { return CDBusServer::sessionDBusServer(); } if (this->ui->rb_DBusSession->isChecked()) { return CDBusServer::sessionBusAddress(); }
if (this->ui->rb_DBusSystem->isChecked()) { return CDBusServer::systemDBusServer(); } if (this->ui->rb_DBusSystem->isChecked()) { return CDBusServer::systemBusAddress(); }
return CDBusServer::fixAddressToDBusAddress( return CDBusServer::normalizeAddress(
this->ui->cb_DBusServerAddress->currentText() + ":" + this->ui->cb_DBusServerAddress->currentText() + ":" +
this->ui->le_DBusServerPort->text()); this->ui->le_DBusServerPort->text());
} }

View File

@@ -20,8 +20,8 @@ namespace XBus
CPlugin::CPlugin() CPlugin::CPlugin()
: m_menu(CMenu::mainMenu().subMenu("XBus")) : m_menu(CMenu::mainMenu().subMenu("XBus"))
{ {
m_startServerMenuItems.push_back(m_menu.item("Start server on session bus", [this]{ startServer(BlackMisc::CDBusServer::sessionDBusServer()); })); m_startServerMenuItems.push_back(m_menu.item("Start server on session bus", [this]{ startServer(BlackMisc::CDBusServer::sessionBusAddress()); }));
m_startServerMenuItems.push_back(m_menu.item("Start server on system bus", [this]{ startServer(BlackMisc::CDBusServer::systemDBusServer()); })); m_startServerMenuItems.push_back(m_menu.item("Start server on system bus", [this]{ startServer(BlackMisc::CDBusServer::systemBusAddress()); }));
m_startServerMenuItems.push_back(m_menu.item("Start server on localhost P2P", [this]{ startServer(BlackMisc::CDBusServer::p2pAddress()); })); m_startServerMenuItems.push_back(m_menu.item("Start server on localhost P2P", [this]{ startServer(BlackMisc::CDBusServer::p2pAddress()); }));
} }