diff options
| author | Manuel Traut <manut@linutronix.de> | 2009-06-23 21:31:19 +0100 |
|---|---|---|
| committer | Manuel Traut <manut@linutronix.de> | 2009-06-23 21:31:19 +0100 |
| commit | 46f636afe5ad22567351391155da76f8a2e00bc6 (patch) | |
| tree | eeb2d13b9e09bfeee4b85616d71838ad27c857af /frameworks | |
| parent | cb5dfc68d3fb4c35295271814715d08820eb2f0a (diff) | |
middleware: added dbus example
Signed-off-by: Manuel Traut <manut@linutronix.de>
Diffstat (limited to 'frameworks')
| -rwxr-xr-x | frameworks/middleware/examples/dbus/compile.sh | 3 | ||||
| -rw-r--r-- | frameworks/middleware/examples/dbus/ping-client.c | 64 | ||||
| -rw-r--r-- | frameworks/middleware/examples/dbus/ping-server.c | 72 | ||||
| -rw-r--r-- | frameworks/middleware/handout_middleware.tex | 191 |
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 |
