diff --git a/src/xswiftbus/dbusconnection.cpp b/src/xswiftbus/dbusconnection.cpp index 69419f0bd..657e93861 100644 --- a/src/xswiftbus/dbusconnection.cpp +++ b/src/xswiftbus/dbusconnection.cpp @@ -26,10 +26,11 @@ namespace XSwiftBus CDBusConnection::CDBusConnection(DBusConnection *connection) { + m_connection.reset(connection); dbus_connection_ref(connection); // Don't exit application, if the connection is disconnected dbus_connection_set_exit_on_disconnect(connection, false); - m_connection.reset(connection); + dbus_connection_add_filter(connection, filterDisconnectedFunction, this, nullptr); } CDBusConnection::~CDBusConnection() @@ -98,6 +99,11 @@ namespace XSwiftBus return m_connection && dbus_connection_get_is_connected(m_connection.get()); } + void CDBusConnection::registerDisconnectedCallback(DisconnectedCallback func) + { + m_disconnectedCallbacks.push_back(func); + } + void CDBusConnection::registerObjectPath(CDBusObject *object, const std::string &interfaceName, const std::string &objectPath, const DBusObjectPathVTable &dbusObjectPathVTable) { (void) interfaceName; @@ -149,4 +155,24 @@ namespace XSwiftBus return obj->setDispatchStatus(connection, status); } + DBusHandlerResult CDBusConnection::filterDisconnectedFunction(DBusConnection *connection, DBusMessage *message, void *data) + { + (void)connection; // unused + + auto *obj = static_cast(data); + + DBusError err; + dbus_error_init(&err); + + if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) + { + for (const auto &cb : obj->m_disconnectedCallbacks) + { + cb(); + } + return DBUS_HANDLER_RESULT_HANDLED; + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } diff --git a/src/xswiftbus/dbusconnection.h b/src/xswiftbus/dbusconnection.h index 41e199c4c..2a26d1234 100644 --- a/src/xswiftbus/dbusconnection.h +++ b/src/xswiftbus/dbusconnection.h @@ -34,6 +34,9 @@ namespace XSwiftBus //! Bus type enum BusType { SessionBus }; + //! Disconnect Callback + using DisconnectedCallback = std::function; + //! Default constructor CDBusConnection(); @@ -41,7 +44,7 @@ namespace XSwiftBus CDBusConnection(DBusConnection *connection); //! Destructor - ~CDBusConnection(); + ~CDBusConnection() override; // The ones below are not implemented yet. // If you need them, make sure that connection reference count is correct @@ -60,6 +63,9 @@ namespace XSwiftBus //! Is connected? bool isConnected() const; + //! Register a disconnected callback + void registerDisconnectedCallback(DisconnectedCallback func); + //! Register DBus object with interfaceName and objectPath. //! \param object //! \param interfaceName @@ -82,6 +88,7 @@ namespace XSwiftBus private: void setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status); static void setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status, void *data); + static DBusHandlerResult filterDisconnectedFunction(DBusConnection *connection, DBusMessage *message, void *data); struct DBusConnectionDeleter { @@ -91,6 +98,7 @@ namespace XSwiftBus CDBusDispatcher *m_dispatcher = nullptr; std::unique_ptr m_connection; CDBusError m_lastError; + std::vector m_disconnectedCallbacks; }; } diff --git a/src/xswiftbus/dbusobject.cpp b/src/xswiftbus/dbusobject.cpp index 471d556f4..b494bf6ba 100644 --- a/src/xswiftbus/dbusobject.cpp +++ b/src/xswiftbus/dbusobject.cpp @@ -20,6 +20,9 @@ namespace XSwiftBus void CDBusObject::setDBusConnection(const std::shared_ptr &dbusConnection) { m_dbusConnection = dbusConnection; + dbusConnectedHandler(); + CDBusConnection::DisconnectedCallback disconnectedHandler = std::bind(&CDBusObject::dbusDisconnectedHandler, this); + m_dbusConnection->registerDisconnectedCallback(disconnectedHandler); } void CDBusObject::registerDBusObjectPath(const std::string &interfaceName, const std::string &objectPath) diff --git a/src/xswiftbus/dbusobject.h b/src/xswiftbus/dbusobject.h index d5753f756..556963f03 100644 --- a/src/xswiftbus/dbusobject.h +++ b/src/xswiftbus/dbusobject.h @@ -36,9 +36,15 @@ namespace XSwiftBus void registerDBusObjectPath(const std::string &interfaceName, const std::string &objectPath); protected: + //! Handler which is called when DBusCconnection is established + virtual void dbusConnectedHandler() {} + //! DBus message handler virtual DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) = 0; + //! Handler which is called when DBusConnection disconnected + virtual void dbusDisconnectedHandler() {} + //! Send DBus signal void sendDBusSignal(const std::string &name); diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index 22514f55d..2b59c03a5 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -445,6 +445,11 @@ namespace XSwiftBus enableFollowPlaneView(callsign); } + void CTraffic::dbusDisconnectedHandler() + { + removeAllPlanes(); + } + const char *introspection_traffic = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE #include "org.swift_project.xswiftbus.traffic.xml" diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index 42def0f3d..796985b6f 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -122,6 +122,8 @@ namespace XSwiftBus int process(); protected: + virtual void dbusDisconnectedHandler() override; + DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override; private: