Hi,
in the attached forwarded message you can find initial
implementation of DBus interface for Matahari - diff
between dbus and master branch in one big patch (for
the complete commit history, check dbus branch).
Implementation - most of the stuff is autogenerated -
GDBus tools + our own XSTL transformation of QMF XML
schema. Currently Host interface is implemented but
now it should be easy to implement missing ones.
It's really an initial try - we are still missing
PolicyKit integration - Matahari does not solve
policy - as it's on Qpid level but we have to ship
default policies for DBus interface.
We tried not to be very intrusive to current master
code, some integration build system changes are
needed.
So the question is - how to merge it properly. Split
it to small patches for master branch and do integration
part in master or do everything in dbus branch and then
merge it in once. I'd really like to avoid too big
changes, especially now, when there's a little time.
So maybe the less intrusive changes and smaller patches
are preferable.
Have a nice holidays!
Jaroslav
----- Forwarded Message -----
From: "Roman Rakus" <rrakus(a)redhat.com>
To: jreznik(a)redhat.com
Cc: rnovacek(a)redhat.com, rrakus(a)redhat.com
Sent: Thursday, December 23, 2010 10:29:12 AM
Subject: [PATCH] Changes between branches master and dbus
---
src/CMakeLists.txt | 38 ++++-
src/cmake/modules/DBusMacros.cmake | 49 +++++
src/common/mh_gobject_class.h | 51 +++++
src/dbus-to-c.xsl | 112 +++++++++++
src/host/CMakeLists.txt | 32 +++
src/host/matahari-host-dbus.c | 324 ++++++++++++++++++++++++++++++++
src/host/org.matahariproject.Host.conf | 18 ++
src/schema-to-dbus.xsl | 196 +++++++++++++++++++
8 files changed, 818 insertions(+), 2 deletions(-)
create mode 100644 src/cmake/modules/DBusMacros.cmake
create mode 100644 src/common/mh_gobject_class.h
create mode 100644 src/dbus-to-c.xsl
create mode 100644 src/host/CMakeLists.txt
create mode 100644 src/host/matahari-host-dbus.c
create mode 100644 src/host/org.matahariproject.Host.conf
create mode 100644 src/schema-to-dbus.xsl
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a67e822..0090ed4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,7 @@
#set(CMAKE_VERBOSE_MAKEFILE ON)
+
+
if(WIN32)
set(VARIANT "windows")
set(SUPPORT_TRACING 0)
@@ -14,10 +16,14 @@ set(MCOMMON_VERSION 0.0.1)
set(MHOST_VERSION 0.0.1)
set(MSRV_VERSION 0.0.1)
+option(WITH-QMF "Build the QMF daemon" ON)
+option(WITH-DBUS "Build the DBus daemon" ON)
+
include(FindPkgConfig)
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/common")
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH} )
@@ -97,6 +103,7 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/include/matahari.h.in
${CMAKE_CURREN
## Modules
pkg_check_modules(glib REQUIRED glib-2.0)
pkg_check_modules(pcre REQUIRED libpcre)
+pkg_check_modules(dbus-glib REQUIRED dbus-glib-1)
if(NOT PKG_CONFIG_FOUND)
message("pkg-config not found")
@@ -131,6 +138,35 @@ else(glib_FOUND)
message(FATAL_ERROR "Glib2 header/library not found.")
endif(glib_FOUND)
+## dbus
+
+include(DBusMacros)
+set(apis host net srv)
+generate_dbus_interfaces(${CMAKE_CURRENT_SOURCE_DIR}/schema.xml ${apis})
+
+set(HOST_DBUS_SOURCE
+ host/matahari-host-dbus.c
+ ${CMAKE_CURRENT_BINARY_DIR}/host/matahari-host-dbus-glue.h
+ ${CMAKE_CURRENT_BINARY_DIR}/host/matahari-host-dbus-properties.h)
+
+# Daemon
+set(M_HOST_DBUS "matahari-host-dbusd")
+add_executable(${M_HOST_DBUS} ${HOST_DBUS_SOURCE})
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/host)
+add_dependencies(${M_HOST_DBUS}
+ ${CMAKE_CURRENT_BINARY_DIR}/host/matahari-host-dbus-glue.h
+ ${CMAKE_CURRENT_BINARY_DIR}/host/matahari-host-dbus-properties.h)
+
+target_link_libraries(${M_HOST_DBUS} mhost )
+
+if(dbus-glib_FOUND)
+ include_directories(${dbus-glib_INCLUDE_DIRS})
+ target_link_libraries(${M_HOST_DBUS} ${dbus-glib_LIBRARIES})
+else(dbus-glib_FOUND)
+ message(FATAL_ERROR "dbus-glib headers/libraries not found.")
+endif(dbus-glib_FOUND)
+
+
## qpid
find_package(QPID REQUIRED)
@@ -187,5 +223,3 @@ install(TARGETS mcommon mhost msrv DESTINATION lib${LIB_SUFFIX})
install(FILES ${SCHEMAS} DESTINATION share/matahari)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/matahari.h DESTINATION include)
-
-
diff --git a/src/cmake/modules/DBusMacros.cmake b/src/cmake/modules/DBusMacros.cmake
new file mode 100644
index 0000000..92e93e6
--- /dev/null
+++ b/src/cmake/modules/DBusMacros.cmake
@@ -0,0 +1,49 @@
+# Generator for files specific to DBus interface
+
+# This macro takes path to schema.xml that describes provided interface
+# Second argument is list of API names for which will be generated c interface
+# files
+macro(generate_dbus_interfaces SCHEMA APIS)
+ find_file(XSLTPROC xsltproc)
+ find_file(BIND_TOOL dbus-binding-tool)
+
+ # Create list of generated dbus interface files
+ set(XMLS "")
+ foreach(API ${APIS})
+ set(XMLS ${XMLS}
${CMAKE_CURRENT_BINARY_DIR}/dbus/org.matahariproject.${API}.xml)
+ endforeach(API ${APIS})
+ message(${XMLS})
+
+ # Convert schema.xml to dbus interfaces
+ add_custom_command(
+ OUTPUT ${XMLS}
+ COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/dbus/
+ COMMAND cd dbus && ${XSLTPROC}
${CMAKE_CURRENT_SOURCE_DIR}/schema-to-dbus.xsl ${SCHEMA}
+ DEPENDS ${SCHEMA}
+ COMMENT "Processing schema.xml with schema-to-dbus.xsl"
+ )
+
+
+ # Convert dbus interface to glue and properties files
+ foreach(API ${APIS})
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${API}/matahari-${API}-dbus-glue.h
+ COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/${API}/
+ COMMAND ${BIND_TOOL} --prefix=matahari --mode=glib-server
+ --output=${CMAKE_CURRENT_BINARY_DIR}/${API}/matahari-${API}-dbus-glue.h
+ ${CMAKE_CURRENT_BINARY_DIR}/dbus/org.matahariproject.${API}.xml
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dbus/org.matahariproject.${API}.xml
+ COMMENT "Generating matahari-${API}-dbus-glue.h"
+ )
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${API}/matahari-${API}-dbus-properties.h
+ COMMAND ${XSLTPROC} --output
${CMAKE_CURRENT_BINARY_DIR}/${API}/matahari-${API}-dbus-properties.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/dbus-to-c.xsl
+ ${CMAKE_CURRENT_BINARY_DIR}/dbus/org.matahariproject.${API}.xml
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dbus/org.matahariproject.${API}.xml
+ COMMENT "Generating matahari-${API}-dbus-properties.h"
+ )
+ endforeach(API ${APIS})
+
+endmacro(generate_dbus_interfaces)
diff --git a/src/common/mh_gobject_class.h b/src/common/mh_gobject_class.h
new file mode 100644
index 0000000..821d0ac
--- /dev/null
+++ b/src/common/mh_gobject_class.h
@@ -0,0 +1,51 @@
+/*
+ * mh_gobject_class.h
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Written by Roman Rakus <rrakus(a)redhat.com>
+ *
+ * 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 MHGOBJECTCLASS_H_
+#define MHGOBJECTCLASS_H_
+
+#define MATAHARI_TYPE (matahari_get_type())
+#define MATAHARI(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MATAHARI_TYPE,
Matahari))
+#define MATAHARI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MATAHARI_TYPE,
MatahariClass))
+#define IS_MATAHARI(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object),
MATAHARI_TYPE))
+#define IS_MATAHARI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MATAHARI_TYPE))
+#define MATAHARI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MATAHARI_TYPE,
MatahariClass))
+
+typedef struct _Matahari Matahari;
+typedef struct _MatahariClass MatahariClass;
+typedef struct _MatahariPrivate MatahariPrivate;
+
+GType
+matahari_get_type(void);
+
+struct _Matahari
+{
+ GObject parent;
+ MatahariPrivate *priv;
+};
+
+struct _MatahariClass
+{
+ GObjectClass parent;
+};
+
+#endif /* MHGOBJECTCLASS_H_ */
diff --git a/src/dbus-to-c.xsl b/src/dbus-to-c.xsl
new file mode 100644
index 0000000..136c781
--- /dev/null
+++ b/src/dbus-to-c.xsl
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="text" indent="no" />
+<xsl:strip-space elements="*" />
+
+<!-- This xsl file is for tranforming dbus interface file to
+ C code that can be used by glib-dbus for automated generating
+ of dbus properties.
+
+ It create enum named Prop with list of properties for internal
+ identification.
+
+ Then it create struct Property which contains enum of property, its name,
+ nick, description, flags (readable, readwrite) and type. Type is then
+ used to automaticly create the property from dbus.
+
+ Last step is to create array of Property structs with info about all
+ properties.
+-->
+
+<xsl:template match="/">
+ <xsl:for-each select="node/interface">
+ <!-- Create enum of the properties -->
+ <xsl:call-template name="enum" />
+ <!-- Define Property struct and create array of it with properties
+ info -->
+ <xsl:call-template name="struct" />
+ </xsl:for-each>
+</xsl:template>
+
+<!-- This is needed for converting properties names to uppercase -->
+<xsl:variable name="smallcase"
select="'abcdefghijklmnopqrstuvwxyz'" />
+<xsl:variable name="uppercase"
select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
+
+<xsl:template name="enum">
+ <!-- Create enum of the properties and first property with id 0 -->
+ <xsl:text>enum Prop {
+ PROP_0,
+ </xsl:text>
+ <!-- Iterate through all properties -->
+ <xsl:for-each select="property">
+ <xsl:value-of select="concat('PROP_', translate(@name,
$smallcase, $uppercase))" />,
+ </xsl:for-each>
+ <xsl:text>};</xsl:text>
+</xsl:template>
+
+<xsl:template name="struct">
+ <!-- Define Property struct -->
+ <xsl:text>
+
+typedef struct {
+ enum Prop prop;
+ gchar *name, *nick, *desc;
+ GParamFlags flags;
+ char type;
+} Property;
+
+</xsl:text>
+ <!-- Create the array of Property structs -->
+ <xsl:value-of select="concat('Property properties_',
substring-after(substring-after(@name, '.'), '.'))" />
+ <xsl:text>[] = { </xsl:text>
+ <!-- Iterate through all properties -->
+ <xsl:for-each select="property">
+ <xsl:text> { </xsl:text>
+ <!-- Enum of the item -->
+ <xsl:value-of select="concat('PROP_', translate(@name,
$smallcase, $uppercase))" />
+ <xsl:text>, "</xsl:text>
+
+ <!-- Name of the item -->
+ <xsl:value-of select="@name" />
+ <xsl:text>", "</xsl:text>
+
+ <!-- Nickname - same as the name -->
+ <xsl:value-of select="@name" />
+ <xsl:text>", "</xsl:text>
+
+ <!-- Description is taken from the comment that is preceding the item -->
+ <xsl:value-of select="preceding::comment()[1]" />
+ <xsl:text>", </xsl:text>
+
+ <!-- Flags - readable or readwrite -->
+ <xsl:choose>
+ <xsl:when test="@access='readwrite'">
+ <xsl:text>G_PARAM_READWRITE</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>G_PARAM_READABLE</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>, '</xsl:text>
+
+ <!-- Type of the property - some must be converted -->
+ <xsl:choose>
+ <!-- Convert dict to type 'e' -->
+ <xsl:when test="@type='a{sv}'">
+ <xsl:text>e</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@type" />
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>'</xsl:text>
+ <xsl:text> }, </xsl:text>
+ </xsl:for-each>
+ <!-- This item is used as sentinel node -->
+ <xsl:text> { PROP_0, NULL, NULL, NULL, 0, '\0'
}, </xsl:text>
+ <xsl:text>};</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt
new file mode 100644
index 0000000..3fdc1e9
--- /dev/null
+++ b/src/host/CMakeLists.txt
@@ -0,0 +1,32 @@
+set(MHOST_VERSION 0.0.1)
+
+# set service name var's
+set(M_HOST_DBUS "matahari-host-dbusd")
+set(M_HOST_QMF "matahari-host-qmfd")
+
+set(DBUS_INTROSPECT "${CMAKE_CURRENT_SOURCE_DIR}/matahari-host-dbus.xml")
+
+set(HOST_DBUS_SOURCE "matahari-host-dbus.c")
+set(HOST_QMF_SOURCE "matahari-host-qmf.cpp")
+
+# Daemon
+add_executable(${M_HOST_DBUS} ${HOST_DBUS_SOURCE})
+target_link_libraries(${M_HOST_DBUS} mhost)
+
+#add_executable(${M_HOST_QMF} ${HOST_QMF_SOURCE})
+#target_link_libraries(${M_HOST_QMF} mhost)
+
+# DBus
+find_file(BIND_TOOL dbus-binding-tool)
+execute_process(COMMAND ${BIND_TOOL}
+ --prefix=matahari --mode=glib-server
+ --output=matahari-host-dbus-glue.h ${DBUS_INTROSPECT}
+# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/fmci})
+)
+
+# Install targets
+# TODO: fix hardcoded paths, should go to libexec
+install(TARGETS ${M_HOST_DBUS} DESTINATION sbin)
+#install(TARGETS ${M_HOST_QMF} DESTINATION sbin)
+install(FILES ${DBUS_INTROSPECT} DESTINATION share/dbus-1/interfaces)
+install(FILES org.matahariproject.Host.conf etc/dbus-1/system.d)
\ No newline at end of file
diff --git a/src/host/matahari-host-dbus.c b/src/host/matahari-host-dbus.c
new file mode 100644
index 0000000..dc631cf
--- /dev/null
+++ b/src/host/matahari-host-dbus.c
@@ -0,0 +1,324 @@
+/*
+ * matahari-host-dbus.c
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Written by Roman Rakus <rrakus(a)redhat.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib-bindings.h>
+
+/* GObject class definition */
+#include "mh_gobject_class.h"
+
+/* Host methods */
+#include "matahari/host.h"
+
+/* Generated properties list */
+#include "matahari-host-dbus-properties.h"
+
+/* DBus names */
+#define HOST_BUS_NAME "org.matahariproject.Host"
+#define HOST_OBJECT_PATH "/org/matahariproject/Host"
+#define HOST_INTERFACE_NAME "org.matahariproject.Host"
+
+/* Private struct in Matahari class */
+#define MATAHARI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MATAHARI_TYPE,
MatahariPrivate))
+
+struct _MatahariPrivate
+{
+ guint update_interval;
+};
+
+/* Dbus methods */
+gboolean
+Host_identify(Matahari* matahari, GError** error)
+{
+// host_identify(5); XXX, not implemented
+ return TRUE;
+}
+
+gboolean
+Host_shutdown(Matahari* matahari, GError** error)
+{
+ host_shutdown();
+ return TRUE;
+}
+
+gboolean
+Host_reboot(Matahari* matahari, GError** error)
+{
+ host_reboot();
+ return TRUE;
+}
+
+/* Generated dbus stuff for host
+ * MUST be after declaration of user defined functions.
+ */
+#include "matahari-host-dbus-glue.h"
+
+
+//TODO: Properties get/set
+static void
+matahari_set_property(GObject *object, guint property_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ Matahari *self = MATAHARI(object);
+ switch (property_id)
+ {
+ case PROP_UPDATE_INTERVAL:
+ self->priv->update_interval = g_value_get_uint (value);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+matahari_get_property(GObject *object, guint property_id, GValue *value,
+ GParamSpec *pspec)
+{
+ Matahari *self = MATAHARI(object);
+ sigar_loadavg_t load;
+ sigar_proc_stat_t procs;
+
+ switch (property_id)
+ {
+ case PROP_UUID:
+ g_value_set_string (value, host_get_uuid());
+ break;
+ case PROP_HOSTNAME:
+ g_value_set_string (value, host_get_hostname());
+ break;
+ case PROP_OS:
+ g_value_set_string (value, host_get_operating_system());
+ break;
+ case PROP_ARCH:
+ g_value_set_string (value, host_get_architecture());
+ break;
+ case PROP_WORDSIZE:
+ g_value_set_uint (value, host_get_cpu_wordsize());
+ break;
+ case PROP_MEMORY:
+ g_value_set_uint64 (value, host_get_memory());
+ break;
+ case PROP_SWAP:
+ g_value_set_uint64 (value, host_get_swap());
+ break;
+ case PROP_CPU_COUNT:
+ g_value_set_uint (value, host_get_cpu_count());
+ break;
+ case PROP_CPU_CORES:
+ g_value_set_uint (value, host_get_cpu_number_of_cores());
+ break;
+ case PROP_CPU_MODEL:
+ g_value_set_string (value, host_get_cpu_model());
+ break;
+ case PROP_CPU_FLAGS:
+ g_value_set_string (value, host_get_cpu_flags());
+ break;
+ case PROP_UPDATE_INTERVAL:
+ g_value_set_uint (value, self->priv->update_interval);
+ break;
+ case PROP_LAST_UPDATED:
+ //TODO Logic here
+ break;
+ case PROP_SEQUENCE:
+ //TODO Logic here
+ break;
+ case PROP_FREE_MEM:
+ g_value_set_uint64 (value, host_get_mem_free());
+ break;
+ case PROP_FREE_SWAP:
+ g_value_set_uint64 (value, host_get_swap_free());
+ break;
+ case PROP_LOAD:
+ //TODO 1/5/15 minute load average - map
+ break;
+ case PROP_PROCESS_STATISTICS:
+ //TODO proc stats - map
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+/* Generate the GObject boilerplate */
+G_DEFINE_TYPE(Matahari, matahari, G_TYPE_OBJECT)
+
+/* Class init */
+static void
+matahari_class_init(MatahariClass *matahari_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(matahari_class);
+ GParamSpec *pspec;
+
+ g_type_class_add_private(matahari_class, sizeof (MatahariPrivate));
+
+ gobject_class->set_property = matahari_set_property;
+ gobject_class->get_property = matahari_get_property;
+
+ //TODO: Proper properties initialization
+ int i;
+ for (i = 0; properties_Host[i].name != NULL; i++)
+ {
+ switch (properties_Host[i].type)
+ {
+ case 's':
+ pspec = g_param_spec_string(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ NULL,
+ properties_Host[i].flags);
+ break;
+ case 'b':
+ pspec = g_param_spec_boolean(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ FALSE,
+ properties_Host[i].flags);
+ break;
+ case 'n':
+ case 'i':
+ pspec = g_param_spec_int(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ G_MININT, G_MAXINT, 0,
+ properties_Host[i].flags);
+ break;
+ case 'x':
+ pspec = g_param_spec_int64(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ G_MININT64, G_MAXINT64, 0,
+ properties_Host[i].flags);
+
+ break;
+ case 'y':
+ case 'q':
+ case 'u':
+ pspec = g_param_spec_uint(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ 0, G_MAXUINT, 0,
+ properties_Host[i].flags);
+ break;
+ case 't':
+ pspec = g_param_spec_uint64(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ 0, G_MAXUINT64, 0,
+ properties_Host[i].flags);
+
+ break;
+ case 'd':
+ pspec = g_param_spec_double(properties_Host[i].name,
+ properties_Host[i].nick,
+ properties_Host[i].desc,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+ properties_Host[i].flags);
+ break;
+ default:
+ g_printerr("Unknown type: %c\n", properties_Host[i].type);
+ pspec = NULL;
+ }
+ if (pspec)
+ g_object_class_install_property(gobject_class, properties_Host[i].prop, pspec);
+ }
+
+ dbus_g_object_type_install_info(MATAHARI_TYPE, &dbus_glib_matahari_object_info);
+}
+
+/* Instance init */
+static void
+matahari_init(Matahari *matahari)
+{
+ MatahariPrivate *priv;
+ matahari->priv = priv = MATAHARI_GET_PRIVATE(matahari);
+ //XXX hardcoded number
+ priv->update_interval = 5;
+}
+
+int
+main(int argc, char** argv)
+{
+ GMainLoop* loop = NULL;
+ DBusGConnection *connection = NULL;
+ GError *error = NULL;
+ GObject *obj = NULL;
+ DBusGProxy *driver_proxy = NULL;
+ guint32 request_name_ret;
+
+ g_type_init();
+ loop = g_main_loop_new(NULL, FALSE);
+
+ /* Obtain a connection to the system bus */
+ connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (!connection)
+ {
+ g_printerr(_("Failed to open connection to bus: %s\n"),
error->message);
+ g_error_free(error);
+ exit(1);
+ }
+
+ obj = g_object_new(MATAHARI_TYPE, NULL);
+ dbus_g_connection_register_g_object(connection, HOST_OBJECT_PATH, obj);
+
+ driver_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+ if (!org_freedesktop_DBus_request_name(driver_proxy, HOST_BUS_NAME, 0,
+ &request_name_ret, &error))
+ {
+ g_printerr(_("Failed to get name: %s\n"), error->message);
+ g_error_free(error);
+ exit(1);
+ }
+
+ switch (request_name_ret)
+ {
+ case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ break;
+ case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+ g_printerr(
+ _("Looks like another server of this type is already running: Reply in
queue\n"));
+ exit(1);
+ case DBUS_REQUEST_NAME_REPLY_EXISTS:
+ g_printerr(
+ _("Looks like another server of this type is already running: Reply
exists\n"));
+ exit(1);
+ case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+ g_printerr(_("We are already running\n"));
+ exit(1);
+ default:
+ g_printerr(_("Unspecified error\n"));
+ exit(1);
+ }
+
+ g_main_loop_run(loop);
+ return 0;
+}
diff --git a/src/host/org.matahariproject.Host.conf
b/src/host/org.matahariproject.Host.conf
new file mode 100644
index 0000000..a86dce8
--- /dev/null
+++ b/src/host/org.matahariproject.Host.conf
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root can own the service -->
+ <policy user="root">
+ <allow own="org.matahariproject.Host"/>
+ </policy>
+
+ <!-- Allow anyone to invoke methods on the interfaces -->
+ <policy context="default">
+ <allow send_destination="org.matahariproject.Host"/>
+ </policy>
+
+</busconfig>
diff --git a/src/schema-to-dbus.xsl b/src/schema-to-dbus.xsl
new file mode 100644
index 0000000..0b526fc
--- /dev/null
+++ b/src/schema-to-dbus.xsl
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+
xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl">
+
+<xsl:variable name="smallcase"
select="'abcdefghijklmnopqrstuvwxyz'" />
+<xsl:variable name="uppercase"
select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
+
+<!-- This xsl transformation takes schema.xml and converts it to multiple
+ DBus interfaces, one per each class.
+
+ The DBus files will be name org.matahariproject.class_name.xml and will
+ be created in current directory. Description of the properties/methods
+ will be added as a comment for future processing.
+-->
+
+<xsl:template match="/">
+ <xsl:variable name="package">
+ <xsl:value-of select="schema/@package" />
+ </xsl:variable>
+ <xsl:for-each select="schema/class">
+ <xsl:variable name="filename"
select="concat('org.matahariproject.', translate(@name, $uppercase,
$smallcase),'.xml')" />
+ <exsl:document method="xml" indent="yes"
version="1.0" encoding="utf-8" href="{$filename}">
+ <node>
+ <interface>
+ <xsl:attribute name="name">
+ <xsl:value-of select="concat($package, '.',
@name)" />
+ </xsl:attribute>
+ <annotation
name="org.freedesktop.DBus.GLib.CSymbol">
+ <xsl:attribute name="value">
+ <xsl:value-of select="@name"/>
+ </xsl:attribute>
+ </annotation>
+ <xsl:for-each select="property|statistic">
+ <!-- What with doc? Add as comment now. -->
+ <xsl:if test="@desc">
+ <xsl:comment>
+ <xsl:value-of select="@desc" />
+ </xsl:comment>
+ </xsl:if>
+ <property>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name" />
+ </xsl:attribute>
+
+ <!-- Tranform data types -->
+ <xsl:call-template name="type" />
+
+ <!-- Tranform access rights -->
+ <xsl:call-template name="access" />
+ </property>
+ </xsl:for-each>
+
+ <!-- Methods -->
+ <xsl:for-each select="method">
+ <!-- What with doc? Add as comment now. -->
+ <xsl:if test="@desc">
+ <xsl:comment>
+ <xsl:value-of select="@desc" />
+ </xsl:comment>
+ </xsl:if>
+ <method>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name" />
+ </xsl:attribute>
+ <xsl:if test="not(arg[@dir='O'])">
+ <annotation
name="org.freedesktop.DBus.GLib.NoReply" value="yes" />
+ </xsl:if>
+ <xsl:for-each select="arg">
+ <arg>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name" />
+ </xsl:attribute>
+
+ <!-- Tranform data types -->
+ <xsl:call-template name="type" />
+
+ <!-- Parameter direction-->
+ <xsl:call-template name="dir" />
+
+ </arg>
+ </xsl:for-each>
+ </method>
+ </xsl:for-each>
+ </interface>
+ </node>
+ </exsl:document>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="type">
+ <!-- Transform data types -->
+ <xsl:choose>
+ <xsl:when test="@type='list'">
+ <!-- Convert list to list of strings -->
+ <xsl:attribute name="type">as</xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="@type='int8'">
+ <xsl:attribute name="type">n</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='int16'">
+ <xsl:attribute name="type">n</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='int32'">
+ <xsl:attribute name="type">i</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='int64'">
+ <xsl:attribute name="type">x</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint8'">
+ <xsl:attribute name="type">y</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint16'">
+ <xsl:attribute name="type">q</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint32'">
+ <xsl:attribute name="type">u</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='uint64'">
+ <xsl:attribute name="type">t</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='bool'">
+ <xsl:attribute name="type">b</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='double'">
+ <xsl:attribute name="type">d</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='float'">
+ <xsl:attribute name="type">d</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='sstr'">
+ <xsl:attribute name="type">s</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='lstr'">
+ <xsl:attribute name="type">s</xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="@type='list'">
+ <!-- Convert list to list of strings -->
+ <xsl:attribute name="type">as</xsl:attribute>
+ </xsl:when>
+
+ <!-- Warning: Uncompatible -->
+ <xsl:when test="@type='absTime'">
+ <xsl:attribute name="type">i</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='deltaTime'">
+ <xsl:attribute name="type">i</xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="@type='uuid'">
+ <xsl:attribute name="type">x</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@type='map'">
+ <xsl:attribute name="type">x</xsl:attribute>
+ </xsl:when>
+
+ <!-- TODO: check if compatible -->
+ <xsl:when test="@type='objId'">
+ <xsl:attribute name="type">o</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="access">
+ <xsl:choose>
+ <xsl:when test="@access='RW'">
+ <xsl:attribute name="access">readwrite</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@access='RO'">
+ <xsl:attribute name="access">read</xsl:attribute>
+ </xsl:when>
+ <!-- No Read-Create in DBus -->
+ <xsl:when test="@access='RC'">
+ <xsl:attribute name="access">readwrite</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="access">read</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="dir">
+ <xsl:choose>
+ <xsl:when test="@dir='I'">
+ <xsl:attribute name="direction">in</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@dir='O'">
+ <xsl:attribute name="direction">out</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
--
1.7.2.3