About creating service on dbus
xor exor
makkalot at gmail.com
Thu Jul 29 08:10:27 PDT 2010
Hi i'm trying to code a service that will be on dbus session bus.
The xml definiton :
<?xml version="1.0" encoding="UTF-8"?>
<node name="/net/skynet/Echo">
<interface name="net.skynet.Echo">
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="server"/>
<method name="EchoString">
<arg type="s" name="original" direction="in" />
<arg type="s" name="echo" direction="out" />
</method>
<!-- Add more methods/signals if you want -->
</interface>
</node>
-----------------------------------------------------------------------------------------------------------
The generated .h file :
/* Generated by dbus-binding-tool; do not edit! */
#ifndef __dbus_glib_marshal_server_object_MARSHAL_H__
#define __dbus_glib_marshal_server_object_MARSHAL_H__
#include <glib-object.h>
G_BEGIN_DECLS
#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 */
/* BOOLEAN:STRING,POINTER,POINTER */
extern void dbus_glib_marshal_server_object_BOOLEAN__STRING_POINTER_POINTER
(GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
void
dbus_glib_marshal_server_object_BOOLEAN__STRING_POINTER_POINTER
(GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const
GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER)
(gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer arg_3,
gpointer data2);
register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 4);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ?
marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_string (param_values + 1),
g_marshal_value_peek_pointer (param_values + 2),
g_marshal_value_peek_pointer (param_values + 3),
data2);
g_value_set_boolean (return_value, v_return);
}
G_END_DECLS
#endif /* __dbus_glib_marshal_server_object_MARSHAL_H__ */
#include <dbus/dbus-glib.h>
static const DBusGMethodInfo dbus_glib_server_object_methods[] = {
{ (GCallback) server_echo_string,
dbus_glib_marshal_server_object_BOOLEAN__STRING_POINTER_POINTER, 0 },
};
const DBusGObjectInfo dbus_glib_server_object_object_info = {
0,
dbus_glib_server_object_methods,
1,
"net.skynet.Echo\0EchoString\0S\0original\0I\0s\0echo\0O\0F\0N\0s\0\0\0",
"\0",
"\0"
};
----------------------------------------------------------------------------------------------------------------------------------------
And the service part :
#include <dbus/dbus-glib-bindings.h>
//Here you can define you own objects !
typedef struct GpkDbus_{
guint dummy;
}GpkDbus;
extern gboolean server_echo_string (GpkDbus *server, gchar *original, gchar
**echo, GError **error);
#include "echo_server_bindings.h"
#define ECHO_SERVICE_NAME "net.skynet.Echo"
#define ECHO_OBJECT_NAME "/net/skynet/Echo"
#define ECHO_INTERFACE_NAME "net.skynet.Echo"
static GMainLoop *loop = NULL;
/**
* echo_service_object_register:
* @connection: What we want to register to
* @object: The GObject we want to register
*
* Return value: success
**/
static gboolean
echo_service_object_register (DBusGConnection *connection, GObject *object)
{
DBusGProxy *bus_proxy = NULL;
GError *error = NULL;
guint request_name_result;
gboolean ret;
/* connect to the bus */
bus_proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
/* get our name */
ret = dbus_g_proxy_call (bus_proxy, "RequestName", &error,
G_TYPE_STRING, ECHO_SERVICE_NAME,
G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
DBUS_NAME_FLAG_REPLACE_EXISTING |
DBUS_NAME_FLAG_DO_NOT_QUEUE,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID);
if (!ret) {
/* abort as the DBUS method failed */
g_warning ("RequestName failed: %s", error->message);
g_error_free (error);
return FALSE;
}
/* free the bus_proxy */
g_object_unref (G_OBJECT (bus_proxy));
/* already running */
if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
return FALSE;
// ERRROR HERE ! ...
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (object),
&dbus_glib_server_object_object_info);
//dbus_g_error_domain_register (GPK_DBUS_ERROR, NULL,
GPK_DBUS_TYPE_ERROR);
dbus_g_connection_register_g_object (connection, ECHO_OBJECT_NAME,
object);
return TRUE;
}
/**
* main:
**/
int
main (int argc, char *argv[])
{
GpkDbus *dbus = NULL;
GError *error = NULL;
gboolean ret;
guint retval = 0;
DBusGConnection *connection;
if (! g_thread_supported ())
g_thread_init (NULL);
dbus_g_thread_init ();
g_type_init ();
loop = g_main_loop_new (NULL, FALSE);
/* get the bus */
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (error) {
g_warning ("%s", error->message);
g_error_free (error);
retval = 1;
goto out;
}
/* try to register */
ret = echo_service_object_register (connection, G_OBJECT (dbus));
if (!ret) {
g_warning ("failed to replace running instance.");
retval = 1;
goto out;
}
/* wait */
g_main_loop_run (loop);
out:
g_main_loop_unref (loop);
g_object_unref (dbus);
return retval;
}
gboolean
server_echo_string (GpkDbus *server, gchar *original, gchar **echo, GError
**error)
{
*echo = g_strdup(original);
if (0)
{
/* We have an error, set the gerror */
g_set_error (error, g_quark_from_static_string ("echo"),
0xdeadbeef,
"Some random problem occured, you're screwed");
return FALSE;
}
return TRUE;
}
---------------------------------------------------------------------------------------------------------
Here are the parts that are confusing :
What should be the 1st parameter of dbus_g_object_type_install_info
function ?
More information about the dbus
mailing list