receiving with dbus-glib

Jonne Zutt j.zutt at tudelft.nl
Fri Apr 27 00:55:19 PDT 2007


Dear dbus experts,

For some time I've been using dbus successfully in my simulation tool,
for sending messages to a visualisation tool. Recently, we decided that
this communication should be bidirectional. In other words, my
simulation tool must also be able to listen to certain dbus messages.

In the below code fragment, sending works just fine, but how should I
proceed in receiving messages? (listening to signals) I should call a
glib mainloop somewhere?

Thanks in advance,
Jonne.

======================== Dbusconnection.xml ========

This is used to generate DbusConnection-glue.hh
  dbus-binding-tool --mode=glib-server DbusConnection.xml >
DbusConnection-glue.hh
	

<?xml version="1.0" encoding="UTF-8" ?>

<node name="/">
	<!--Note on names: the interface should always be preceded by some
interface. This prefix should also be attached to the names on which
servers/services are known on the bus. -->
  <interface name="some.SampleInterface">
		<method name="SendMessage">
		<arg type="as" direction="in"/>
		</method>
  </interface>
</node>

============================= connection.cc ========

initDBUS() gets called at initialisation time, sendDBUS() whenever I
want to send a message. receiveDBUS() is never called and its
implementation is incorrect.

static void lose(const char *str, ...) {
  va_list args;
  va_start(args, str);
  vfprintf(stderr, str, args);
  fputc('\n', stderr);
  va_end(args);
  //exit(1);
}

static void lose_gerror(const char *prefix, GError *error) {
  lose("%s: %s", prefix, error->message);
}

GType some_object_get_type (void);
G_DEFINE_TYPE(SomeObject, some_object, G_TYPE_OBJECT)
gboolean _send_message(SomeObject* obj, char** msgArray, GError**
error);

#include "DbusConnection-glue.hh"

static void some_object_init(__attribute__ ((unused)) SomeObject *obj) {
}

static void some_object_class_init(__attribute__ ((unused))
SomeObjectClass *klass) {
}

gboolean _send_message(SomeObject *obj, char** msgArray, GError** error)
{
  Connector *myconn = obj->mc;

  for(int i=0; msgArray[i] != 0; i++) {
	cout << "_send_message :: " << msgArray[i] << endl;
  }

  return TRUE;
}

/* Initialize DBUS */
void Connector::initDBUS() {
  g_type_init();

  DBusGConnection *bus;
  DBusGProxy *bus_proxy;
  GError *error = 0;
  SomeObject *obj;
  guint request_name_result;

  if(!(bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error))) {
	lose_gerror("Could not connect to session bus", error);
  }
  
  dbus_mainloop = g_main_loop_new(0, FALSE);
  dbus_g_object_type_install_info(SOME_TYPE_OBJECT,
&dbus_glib__object_info);
  
  dbus_proxy = dbus_g_proxy_new_for_name(bus, dbus_other_name.c_str(),
	  "/SomeObject", "some.SampleInterface");

  bus_proxy = dbus_g_proxy_new_for_name(bus, "org.freedesktop.DBus",
	  "/org/freedesktop/DBus", "org.freedesktop.DBus");

  if(!dbus_g_proxy_call(bus_proxy, "RequestName", &error,
		G_TYPE_STRING, dbus_own_name.c_str(),
		G_TYPE_UINT, 0, G_TYPE_INVALID,
		G_TYPE_UINT, &request_name_result, G_TYPE_INVALID)) {
	lose_gerror("Failed to acquire name", error);
  }

  obj = (SomeObject*) g_object_new(SOME_TYPE_OBJECT, 0);
  obj->mc = this;
  dbus_g_connection_register_g_object(bus,
	  "/SomeObject", G_OBJECT (obj));


}

/* Send DBUS signal */
void Connector::sendDBUS(string msg) {
  GError *error = 0;
  char **sendArray = g_strsplit(msg.c_str(), " ", 0);
  
#if CONNECTOR_VERBOSITY > 5
  cout << "Connector::sendDBUS " << msg << endl;
#endif
  
#ifdef DBUS_SYNCHRONOUS
  if(!dbus_g_proxy_call(dbus_proxy, "SendMessage",
		&error, G_TYPE_STRV, sendArray, 
		G_TYPE_INVALID, G_TYPE_INVALID)) {
	lose_gerror("Failed to send message (synchronous)", error);
  }
#else
  DBusGProxyCall* callID;
  callID = dbus_g_proxy_begin_call(dbus_proxy, "SendMessage",
	  NULL, NULL, NULL, G_TYPE_STRV, sendArray, G_TYPE_INVALID);
  if(!dbus_g_proxy_end_call(dbus_proxy, callID,
		&error, G_TYPE_INVALID)) {
	lose_gerror("Failed to send message (asynchronous)", error);
  }
#endif

  g_strfreev(sendArray);
}

/* Receive DBUS signal */
Status* Connector::receiveDBUS() {
  GError *error = 0;
  char **receiveArray = 0;

#ifdef DBUS_SYNCHRONOUS
  if(!dbus_g_proxy_call(dbus_proxy, "SendMessage",
		&error, G_TYPE_STRV, receiveArray,
		G_TYPE_INVALID, G_TYPE_INVALID)) {
	lose_gerror("Failed to receive message (synchronous)", error);
  }
#else
  DBusGProxyCall* callID;
  callID = dbus_g_proxy_begin_call(dbus_proxy, "SendMessage",
	  NULL, NULL, NULL, G_TYPE_STRV, receiveArray, G_TYPE_INVALID);
  if(!dbus_g_proxy_end_call(dbus_proxy, callID,
		&error, G_TYPE_INVALID)) {
	lose_gerror("Failed to receive message (asynchronous)", error);
  }
#endif

  return new Status();
}

/* Close DBUS connection */
void Connector::deinitDBUS() {
  g_main_destroy(dbus_mainloop);
  g_object_unref(G_OBJECT (dbus_proxy));
}

================================================================



More information about the dbus mailing list