summaryrefslogtreecommitdiffstats
path: root/lib/DBus
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DBus')
-rw-r--r--lib/DBus/DBusManager.cpp203
-rw-r--r--lib/DBus/DBusManager.h55
-rw-r--r--lib/DBus/Makefile.am11
-rw-r--r--lib/DBus/marshal.c51
-rw-r--r--lib/DBus/marshal.h15
-rw-r--r--lib/DBus/marshal.list1
-rw-r--r--lib/DBus/test.cpp76
7 files changed, 412 insertions, 0 deletions
diff --git a/lib/DBus/DBusManager.cpp b/lib/DBus/DBusManager.cpp
new file mode 100644
index 00000000..0b2cb97f
--- /dev/null
+++ b/lib/DBus/DBusManager.cpp
@@ -0,0 +1,203 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "DBusManager.h"
+#include <iostream>
+#include <marshal.h>
+
+// only for testing - used by LoopSend()
+static gboolean send_message(DBusGConnection *con)
+{
+ DBusMessage *message;
+ /* Create a new signal "Crash" on the "com.redhat.CrashCatcher" interface,
+ * from the object "/com/redhat/CrashCatcher". */
+ message = dbus_message_new_signal("/com/redhat/CrashCatcher/Crash",
+ "com.redhat.CrashCatcher", "Crash");
+ if(!message){
+ fprintf(stderr,"Message creating error");
+ }
+ char *progname = "Foo";
+ /* Append some info to the signal */
+ dbus_message_append_args(message,DBUS_TYPE_STRING, &progname, DBUS_TYPE_INVALID);
+ /* get the DBusConnection */
+ DBusConnection *dbus_con = dbus_g_connection_get_connection(con);
+ /* Send the signal via low level dbus function coz glib doesn't seem to work */
+ if(!dbus_connection_send(dbus_con, message, NULL)){
+ printf("Error while sending message\n");
+ }
+ printf("flushing bus %p\n", dbus_con);
+ dbus_connection_flush(dbus_con);
+ /* Free the signal */
+ dbus_message_unref(message);
+ /* Tell the user we send a signal */
+ g_print("Message sent!\n");
+ /* Return TRUE to tell the event loop we want to be called again */
+ return TRUE;
+}
+
+
+CDBusManager::CDBusManager()
+{
+ GError *error = NULL;
+ g_type_init();
+ /* first we need to connect to dbus */
+ m_nBus = dbus_g_bus_get(DBUS_BUS, &error);
+ if(!m_nBus)
+ throw std::string("Couldn't connect to dbus") + error->message;
+}
+
+CDBusManager::~CDBusManager()
+{
+}
+
+/* register name com.redhat.CrashCatcher on dbus */
+void CDBusManager::RegisterService()
+{
+ GError *error = NULL;
+ guint request_name_result;
+ g_type_init();
+ // then we need a proxy to talk to dbus
+ m_nBus_proxy = dbus_g_proxy_new_for_name(m_nBus, DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ if(!m_nBus_proxy){
+ std::cerr << "Error while creating dbus proxy!" << error->message << std::endl;
+ }
+ /* and register our name */
+ if (!dbus_g_proxy_call(m_nBus_proxy, "RequestName", &error,
+ G_TYPE_STRING, CC_DBUS_NAME,
+ G_TYPE_UINT, 0,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &request_name_result,
+ G_TYPE_INVALID))
+ {
+ throw std::string("Failed to acquire com.redhat.CrashCatcher:") + error->message ;
+ }
+#ifdef DEBUG
+ std::cout << "Service running" << std::endl;
+#endif
+}
+
+void CDBusManager::ConnectToDaemon()
+{
+ GError *error = NULL;
+ guint request_name_result;
+ g_type_init();
+ /* create a proxy object to talk and listen to CC daemon */
+ m_nCCBus_proxy = dbus_g_proxy_new_for_name_owner(m_nBus, CC_DBUS_NAME,
+ CC_DBUS_PATH_NOTIFIER,
+ CC_DBUS_IFACE, &error);
+ if(!m_nCCBus_proxy){
+#ifdef DEBUG
+ std::cerr << "Couldn't connect to daemon via dbus: " << error->message << std::endl;
+#endif
+ throw std::string(error->message);
+ }
+#ifdef DEBUG
+ std::cout << "Connected! Waiting for signals\n" << std::endl;
+#endif
+}
+
+void CDBusManager::RegisterToMessage(const std::string& pMessage, GCallback handler, void * data, GClosureNotify free_data_func)
+{
+#ifdef DEBUG
+ std::cout << "Trying to register" << std::endl;
+#endif /*DEBUG*/
+ /* Register dbus signal marshaller */
+ dbus_g_object_register_marshaller(marshal_VOID__STRING,
+ G_TYPE_NONE, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal(m_nCCBus_proxy,"Crash",G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(m_nCCBus_proxy,"Crash",handler,NULL, NULL);
+#ifdef DEBUG
+ std::cout << "Register done" << std::endl;
+#endif /*DEBUG*/
+}
+
+bool CDBusManager::GSendMessage(const std::string& pMessage, const std::string& pMessParam)
+{
+ DBusMessage *message;
+ /* Create a new signal "Crash" on the "com.redhat.CrashCatcher" interface,
+ * from the object "/com/redhat/CrashCatcher/Crash". */
+ message = dbus_message_new_signal ("/com/redhat/CrashCatcher/Crash",
+ "com.redhat.CrashCatcher", pMessage.c_str());
+ if(!message){
+ std::cerr << "Message creating error" << std::endl;
+ }
+#ifdef DEBUG
+ std::cerr << message << std::endl;
+#endif
+ const char *progname = pMessParam.c_str();
+ /* Append some info to the signal */
+ dbus_message_append_args(message,DBUS_TYPE_STRING, &progname, DBUS_TYPE_INVALID);
+ /* Send the signal */
+ dbus_g_proxy_send(m_nCCBus_proxy, message, NULL);
+ /* Free the signal */
+ dbus_message_unref(message);
+#ifdef DEBUG
+ g_print("Message sent!\n");
+#endif
+ /* Return TRUE to tell the event loop we want to be called again */
+ return TRUE;
+}
+
+bool CDBusManager::SendMessage(const std::string& pMessage, const std::string& pMessParam)
+{
+ DBusMessage *message;
+ const char *progname = pMessParam.c_str();
+ /* Create a new signal "Crash" on the "com.redhat.CrashCatcher" interface,
+ * from the object "/com/redhat/CrashCatcher/Crash". */
+ message = dbus_message_new_signal ("/com/redhat/CrashCatcher/Crash",
+ "com.redhat.CrashCatcher", pMessage.c_str());
+ if(!message){
+ std::cerr << "Message creating error" << std::endl;
+ }
+#ifdef DEBUG
+ std::cerr << message << std::endl;
+#endif
+ /* Add program name as the message argument */
+ dbus_message_append_args(message,DBUS_TYPE_STRING, &progname, DBUS_TYPE_INVALID);
+ /* Send the signal */
+ DBusConnection *dbus_con = dbus_g_connection_get_connection(m_nBus);
+ /* Send the signal via low level dbus functio coz glib sucks */
+ if(!dbus_connection_send(dbus_con, message, NULL)){
+ throw "Error while sending message";
+ }
+ /* flush the connection, otherwise, it won't show on dbus? */
+ dbus_connection_flush(dbus_con);
+ /* Free the signal */
+ dbus_message_unref(message);
+#ifdef DEBUG
+ g_print("Message sent!\n");
+#endif
+ /* Return TRUE to tell the event loop we want to be called again */
+ return TRUE;
+}
+
+
+// just for testing purposes
+void CDBusManager::LoopSend()
+{
+ g_timeout_add(1000, (GSourceFunc)send_message, m_nBus);
+}
+
+void CDBusManager::Unregister()
+{
+ std::cerr << "Unregister" << std::endl;
+}
diff --git a/lib/DBus/DBusManager.h b/lib/DBus/DBusManager.h
new file mode 100644
index 00000000..e3537f89
--- /dev/null
+++ b/lib/DBus/DBusManager.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DBUS_H_
+#define DBUS_H_
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <string>
+
+#define CC_DBUS_NAME "com.redhat.CrashCatcher"
+#define CC_DBUS_PATH "/com/redhat/CrashCatcher"
+#define CC_DBUS_IFACE "com.redhat.CrashCatcher"
+#define DBUS_BUS DBUS_BUS_SYSTEM
+#define CC_DBUS_PATH_NOTIFIER "/com/redhat/CrashCatcher/Crash"
+
+class CDBusManager
+{
+ private:
+ DBusGConnection *m_nBus;
+ DBusGProxy *m_nBus_proxy;
+ DBusGProxy *m_nCCBus_proxy;
+
+ public:
+ CDBusManager();
+ ~CDBusManager();
+ bool SendMessage(const std::string& pMessage, const std::string& pMessParam);
+ bool GSendMessage(const std::string& pMessage, const std::string& pMessParam);
+ void RegisterService();
+ void ConnectToService();
+ void ConnectToDaemon();
+ void LoopSend();
+ void Unregister();
+ void RegisterToMessage(const std::string& pMessage, GCallback handler, void * data, GClosureNotify free_data_func);
+};
+
+#endif /*DBUS_H_*/
diff --git a/lib/DBus/Makefile.am b/lib/DBus/Makefile.am
new file mode 100644
index 00000000..0d4d9f6e
--- /dev/null
+++ b/lib/DBus/Makefile.am
@@ -0,0 +1,11 @@
+lib_LTLIBRARIES = libDBus.la
+libDBus_la_SOURCES = DBusManager.cpp DBusManager.h marshal.c marshal.h
+libDBus_la_LDFLAGS = -version-info 0:1:0
+libDBus_la_LIBADD = $(DBUS_GLIB_LIBS)
+libDBus_la_CPPFLAGS = $(DBUS_GLIB_CFLAGS)
+
+
+check_PROGRAMS = test
+test_SOURCES = test.cpp
+test_LDADD = libDBus.la $(DL_LIBS)
+test_CPPFLAGS = $(DBUS_GLIB_CFLAGS)
diff --git a/lib/DBus/marshal.c b/lib/DBus/marshal.c
new file mode 100644
index 00000000..247bf1bb
--- /dev/null
+++ b/lib/DBus/marshal.c
@@ -0,0 +1,51 @@
+
+#include <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:STRING (marshal.list:1) */
+
diff --git a/lib/DBus/marshal.h b/lib/DBus/marshal.h
new file mode 100644
index 00000000..60608245
--- /dev/null
+++ b/lib/DBus/marshal.h
@@ -0,0 +1,15 @@
+
+#ifndef __marshal_MARSHAL_H__
+#define __marshal_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* VOID:STRING (marshal.list:1) */
+#define marshal_VOID__STRING g_cclosure_marshal_VOID__STRING
+
+G_END_DECLS
+
+#endif /* __marshal_MARSHAL_H__ */
+
diff --git a/lib/DBus/marshal.list b/lib/DBus/marshal.list
new file mode 100644
index 00000000..30ba5d8d
--- /dev/null
+++ b/lib/DBus/marshal.list
@@ -0,0 +1 @@
+VOID:STRING
diff --git a/lib/DBus/test.cpp b/lib/DBus/test.cpp
new file mode 100644
index 00000000..8f1d66cf
--- /dev/null
+++ b/lib/DBus/test.cpp
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "DBusManager.h"
+#include <cstring>
+#include <iostream>
+#include <climits>
+#include <stdlib.h>
+
+static void
+print_cb(DBusGProxy *proxy, char* progname, gpointer user_data)
+{
+ DBusError error;
+ dbus_error_init (&error);
+ std::cerr << "Application " << progname << " has crashed!" << std::endl;
+}
+
+int main(int argc, char** argv){
+ GMainLoop *mainloop;
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ //no sanity check, it's just a testing program!
+ if (argc < 2){
+ std::cout << "Usage: " << argv[0] << " {s|c}" << std::endl;
+ return 0;
+ }
+ //service
+ if (strcmp(argv[1], "s") == 0){
+ std::cout << "Service: " << std::endl;
+ CDBusManager dm;
+ try
+ {
+ dm.RegisterService();
+ }
+ catch(std::string err)
+ {
+ std::cerr << err << std::endl;
+ return -1;
+ }
+ dm.LoopSend();
+
+ g_main_loop_run(mainloop);
+ }
+ //client
+ else if (strcmp(argv[1], "c") == 0){
+ CDBusManager dm;
+ try
+ {
+ dm.ConnectToService();
+ }
+ catch(std::string error)
+ {
+ std::cerr << error << std::endl;
+ return -1;
+ }
+ dm.RegisterToMessage("Crash",G_CALLBACK(print_cb),NULL,NULL);
+ g_main_loop_run(mainloop);
+ }
+ return 0;
+}