summaryrefslogtreecommitdiff
path: root/frameworks
diff options
context:
space:
mode:
authorManuel Traut <manut@linutronix.de>2009-06-23 21:31:19 +0100
committerManuel Traut <manut@linutronix.de>2009-06-23 21:31:19 +0100
commit46f636afe5ad22567351391155da76f8a2e00bc6 (patch)
treeeeb2d13b9e09bfeee4b85616d71838ad27c857af /frameworks
parentcb5dfc68d3fb4c35295271814715d08820eb2f0a (diff)
middleware: added dbus example
Signed-off-by: Manuel Traut <manut@linutronix.de>
Diffstat (limited to 'frameworks')
-rwxr-xr-xframeworks/middleware/examples/dbus/compile.sh3
-rw-r--r--frameworks/middleware/examples/dbus/ping-client.c64
-rw-r--r--frameworks/middleware/examples/dbus/ping-server.c72
-rw-r--r--frameworks/middleware/handout_middleware.tex191
4 files changed, 329 insertions, 1 deletions
diff --git a/frameworks/middleware/examples/dbus/compile.sh b/frameworks/middleware/examples/dbus/compile.sh
new file mode 100755
index 0000000..d2b2822
--- /dev/null
+++ b/frameworks/middleware/examples/dbus/compile.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+gcc -o server -lrt -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 ping-server.c
+gcc -o client -lrt -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 ping-client.c
diff --git a/frameworks/middleware/examples/dbus/ping-client.c b/frameworks/middleware/examples/dbus/ping-client.c
new file mode 100644
index 0000000..e3035e4
--- /dev/null
+++ b/frameworks/middleware/examples/dbus/ping-client.c
@@ -0,0 +1,64 @@
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <time.h>
+
+static gboolean send_ping (DBusConnection *bus);
+static const char *v_STRING;
+
+int main (int argc, char **argv)
+{
+ GMainLoop *loop;
+ DBusConnection *bus;
+ DBusError error;
+
+ if (argc > 1)
+ v_STRING = argv[1];
+ else
+ v_STRING = "no arg given";
+
+ /* Create a new event loop to run in */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* Get a connection to the session bus */
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+ if (!bus) {
+ g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+
+ /* Set up this connection to work in a GLib event loop */
+ dbus_connection_setup_with_g_main (bus, NULL);
+ /* Every second call send_ping() with the bus as an argument*/
+ g_timeout_add (1000, (GSourceFunc)send_ping, bus);
+
+ /* Start the event loop */
+ g_main_loop_run (loop);
+ return 0;
+}
+
+static gboolean send_ping (DBusConnection *bus)
+{
+ DBusMessage *message;
+ struct timespec tx_time;
+ struct timespec done_time;
+
+ message = dbus_message_new_signal ("/de/linutronix/Ping",
+ "de.linutronix.Ping", "Ping");
+ /* Append the string to the signal */
+ dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &v_STRING,
+ DBUS_TYPE_INVALID);
+ clock_gettime(CLOCK_MONOTONIC, &tx_time);
+ /* Send the signal */
+ dbus_connection_send (bus, message, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &done_time);
+ g_print("%d:%d\n%d:%d\n\n", tx_time.tv_sec, tx_time.tv_nsec/1000,
+ done_time.tv_sec, done_time.tv_nsec/1000);
+ /* Free the signal now we have finished with it */
+ dbus_message_unref (message);
+ /* Return TRUE to tell the event loop we want to be called again */
+ return TRUE;
+}
diff --git a/frameworks/middleware/examples/dbus/ping-server.c b/frameworks/middleware/examples/dbus/ping-server.c
new file mode 100644
index 0000000..36dd122
--- /dev/null
+++ b/frameworks/middleware/examples/dbus/ping-server.c
@@ -0,0 +1,72 @@
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <time.h>
+
+static DBusHandlerResult signal_filter
+ (DBusConnection *connection, DBusMessage *message, void *user_data);
+
+int main(int argc, char **argv)
+{
+ GMainLoop *loop;
+ DBusConnection *bus;
+ DBusError error;
+
+ loop = g_main_loop_new (NULL, FALSE);
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+
+ if (!bus) {
+ g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+
+ dbus_connection_setup_with_g_main (bus, NULL);
+ /* listening to messages from all objects as no path is specified */
+ dbus_bus_add_match (bus, "type='signal',interface='de.linutronix.Ping'",
+ &error);
+ dbus_connection_add_filter (bus, signal_filter, loop, NULL);
+ g_main_loop_run (loop);
+
+ return 0;
+}
+
+static DBusHandlerResult signal_filter
+ (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ /* User data is the event loop we are running in */
+ GMainLoop *loop = user_data;
+
+ /* A signal from the bus saying we are about to be disconnected */
+ if (dbus_message_is_signal(message, "org.freedesktop.Local",
+ "Disconnected"))
+ {
+ /* Tell the main loop to quit */
+ g_main_loop_quit (loop);
+ /* We have handled this message, don't pass it on */
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else if (dbus_message_is_signal (message, "de.linutronix.Ping", "Ping"))
+ {
+ DBusError error;
+ char *s;
+
+ dbus_error_init (&error);
+
+ if (dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &s,
+ DBUS_TYPE_INVALID))
+ {
+ struct timespec rx_time;
+ clock_gettime(CLOCK_MONOTONIC, &rx_time);
+ g_print("ping received: %s - %d:%d\n", s, rx_time.tv_sec,
+ rx_time.tv_nsec/1000);
+ // dbus_free (s);
+ } else {
+ g_print("ping received, but error getting message: %s\n", error.message);
+ dbus_error_free (&error);
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
diff --git a/frameworks/middleware/handout_middleware.tex b/frameworks/middleware/handout_middleware.tex
index c6e3145..39967ba 100644
--- a/frameworks/middleware/handout_middleware.tex
+++ b/frameworks/middleware/handout_middleware.tex
@@ -4,6 +4,26 @@
\usepackage{lxheaders}
\usepackage{lxextras}
+\lstset{
+ language=C++,
+ numbers=left,
+ stepnumber=1,
+ numbersep=5pt,
+ numberstyle=\tiny,
+ breaklines=true,
+ breakautoindent=true,
+ postbreak=\space,
+ tabsize=2,
+ basicstyle=\ttfamily\footnotesize,
+ showspaces=false,
+ showstringspaces=false,
+ extendedchars=true,
+ %backgroundcolor=\color{lbcolor},
+ keywordstyle=\bf ,
+ commentstyle=\color{green},
+ stringstyle=\color{red}
+}
+
\begin{document}
\section*{Middleware}
@@ -225,9 +245,178 @@ On the other hand, the framework is complex and difficult to learn.
\subsection*{Exercises}
+An application should be created, to send a message to the 'server' with a
+variable payload, that the time needed for the call / return of the call can be
+measured in the client.
+
+The above described application will be implemented with ACE/TAO RTCORBA and
+the D-Bus glib bindings:
+
\subsubsection*{ACE/TAO RTCORBA ping-pong}
-\subsubsection*{D-Bus GLib bindings ping-pong}
+\subsubsection*{D-Bus glib bindings ping-pong}
+
+First \cmd{ping-server.c} will be created to host the ping object:
+
+\begin{lstlisting}
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <time.h>
+
+static DBusHandlerResult signal_filter
+ (DBusConnection *connection, DBusMessage *message, void *user_data);
+
+int main(int argc, char **argv)
+{
+ GMainLoop *loop;
+ DBusConnection *bus;
+ DBusError error;
+
+ loop = g_main_loop_new (NULL, FALSE);
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+
+ if (!bus) {
+ g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+
+ dbus_connection_setup_with_g_main (bus, NULL);
+ /* listening to messages from all objects as no path is specified */
+ dbus_bus_add_match (bus, "type='signal',interface='de.linutronix.Ping'",
+ &error);
+ dbus_connection_add_filter (bus, signal_filter, loop, NULL);
+ g_main_loop_run (loop);
+
+ return 0;
+}
+
+static DBusHandlerResult signal_filter
+ (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ /* User data is the event loop we are running in */
+ GMainLoop *loop = user_data;
+
+ /* A signal from the bus saying we are about to be disconnected */
+ if (dbus_message_is_signal(message, "org.freedesktop.Local",
+ "Disconnected"))
+ {
+ /* Tell the main loop to quit */
+ g_main_loop_quit (loop);
+ /* We have handled this message, don't pass it on */
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else if (dbus_message_is_signal (message, "de.linutronix.Ping", "Ping"))
+ {
+ DBusError error;
+ char *s;
+
+ dbus_error_init (&error);
+
+ if (dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &s,
+ DBUS_TYPE_INVALID))
+ {
+ struct timespec rx_time;
+ clock_gettime(CLOCK_MONOTONIC, &rx_time);
+ g_print("ping received: %s - %d:%d\n", s, rx_time.tv_sec,
+ rx_time.tv_nsec/1000);
+ // dbus_free (s);
+ } else {
+ g_print("ping received, but error getting message: %s\n", error.message);
+ dbus_error_free (&error);
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+\end{lstlisting}
+
+The server application will be compiled with the following command:
+
+\cmd{gcc -o server `pkg-config --libs --cflags dbus-glib-1` -lrt ping-server.c}
+
+Next a file \cmd{ping-client.c} with the following content is created:
+
+\begin{lstlisting}
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <time.h>
+
+static gboolean send_ping (DBusConnection *bus);
+static const char *v_STRING;
+
+int main (int argc, char **argv)
+{
+ GMainLoop *loop;
+ DBusConnection *bus;
+ DBusError error;
+
+ if (argc > 1)
+ v_STRING = argv[1];
+ else
+ v_STRING = "no arg given";
+
+ /* Create a new event loop to run in */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* Get a connection to the session bus */
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+ if (!bus) {
+ g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+
+ /* Set up this connection to work in a GLib event loop */
+ dbus_connection_setup_with_g_main (bus, NULL);
+ /* Every second call send_ping() with the bus as an argument*/
+ g_timeout_add (1000, (GSourceFunc)send_ping, bus);
+
+ /* Start the event loop */
+ g_main_loop_run (loop);
+ return 0;
+}
+
+static gboolean send_ping (DBusConnection *bus)
+{
+ DBusMessage *message;
+ struct timespec tx_time;
+ struct timespec done_time;
+
+ message = dbus_message_new_signal ("/de/linutronix/Ping",
+ "de.linutronix.Ping", "Ping");
+ /* Append the string to the signal */
+ dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &v_STRING,
+ DBUS_TYPE_INVALID);
+ clock_gettime(CLOCK_MONOTONIC, &tx_time);
+ /* Send the signal */
+ dbus_connection_send (bus, message, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &done_time);
+ g_print("%d:%d\n%d:%d\n\n", tx_time.tv_sec, tx_time.tv_nsec/1000,
+ done_time.tv_sec, done_time.tv_nsec/1000);
+ /* Free the signal now we have finished with it */
+ dbus_message_unref (message);
+ /* Return TRUE to tell the event loop we want to be called again */
+ return TRUE;
+}
+\end{lstlisting}
+
+The client application will be compiled with the following command:
+
+\cmd{gcc -o client `pkg-config --libs --cflags dbus-glib-1` -lrt ping-client.c}
+
+To run the applications start them with:
+\begin{itemize}
+\item \cmd{./client WhatEverYouWantAsPayLoad}
+\item \cmd{./server}
+\end{itemize}
+
+The order, which application is started first doesn't matter. Take care that
+the \cmd{dbus-daemon} is running.
\begin{thebibliography}{9}%use this if you have <=9 bib refs
%\begin{thebibliography}{99}%use this if you have >9 bib refs