summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2007-06-19 17:44:09 +0000
committerMarcel Holtmann <marcel@holtmann.org>2007-06-19 17:44:09 +0000
commitfbba4be5b162fdffe8e12e3b1e0fa11629436600 (patch)
treee55d63f341e5e06ac00a047aa605ae2fc35296b7
parent7af081a7d55261ab6266c87ff007a3105a38692f (diff)
More work on private D-Bus server
-rw-r--r--common/dbus.c145
-rw-r--r--common/dbus.h5
-rw-r--r--daemon/echo.c41
-rw-r--r--hcid/server.c4
4 files changed, 161 insertions, 34 deletions
diff --git a/common/dbus.c b/common/dbus.c
index db50fcc9..ef3188d9 100644
--- a/common/dbus.c
+++ b/common/dbus.c
@@ -61,6 +61,12 @@ struct watch_info {
GIOChannel *io;
DBusConnection *conn;
};
+
+struct server_info {
+ guint watch_id;
+ GIOChannel *io;
+ DBusServer *server;
+};
#endif
struct disconnect_data {
@@ -371,6 +377,75 @@ static DBusHandlerResult disconnect_filter(DBusConnection *conn,
}
#ifndef HAVE_DBUS_GLIB
+static dbus_int32_t server_slot = -1;
+
+static gboolean server_func(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+ DBusWatch *watch = data;
+ int flags = 0;
+
+ if (cond & G_IO_IN) flags |= DBUS_WATCH_READABLE;
+ if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
+ if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP;
+ if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR;
+
+ dbus_watch_handle(watch, flags);
+
+ return TRUE;
+}
+
+static dbus_bool_t add_server(DBusWatch *watch, void *data)
+{
+ GIOCondition cond = G_IO_HUP | G_IO_ERR;
+ DBusServer *server = data;
+ struct server_info *info;
+ int fd, flags;
+
+ if (!dbus_watch_get_enabled(watch))
+ return TRUE;
+
+ info = g_new(struct server_info, 1);
+
+ fd = dbus_watch_get_fd(watch);
+ info->io = g_io_channel_unix_new(fd);
+ info->server = dbus_server_ref(server);
+
+ dbus_watch_set_data(watch, info, NULL);
+
+ flags = dbus_watch_get_flags(watch);
+
+ if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN;
+ if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT;
+
+ info->watch_id = g_io_add_watch(info->io, cond, server_func, watch);
+
+ return TRUE;
+}
+
+static void remove_server(DBusWatch *watch, void *data)
+{
+ struct server_info *info = dbus_watch_get_data(watch);
+
+ dbus_watch_set_data(watch, NULL, NULL);
+
+ if (info) {
+ g_source_remove(info->watch_id);
+ g_io_channel_unref(info->io);
+ dbus_server_unref(info->server);
+ g_free(info);
+ }
+}
+
+static void server_toggled(DBusWatch *watch, void *data)
+{
+ /* Because we just exit on OOM, enable/disable is
+ * no different from add/remove */
+ if (dbus_watch_get_enabled(watch))
+ add_server(watch, data);
+ else
+ remove_server(watch, data);
+}
+
static gboolean message_dispatch_cb(void *data)
{
DBusConnection *connection = data;
@@ -520,23 +595,27 @@ static void dispatch_status_cb(DBusConnection *conn,
}
#endif
-DBusConnection *init_dbus(const char *name,
- void (*disconnect_cb)(void *), void *user_data)
+void setup_dbus_server_with_main_loop(DBusServer *server)
{
- struct disconnect_data *dc_data;
- DBusConnection *conn;
- DBusError err;
+#ifdef HAVE_DBUS_GLIB
+ dbus_server_setup_with_g_main(server, NULL);
+#else
+ dbus_server_allocate_data_slot(&server_slot);
+ if (server_slot < 0)
+ return;
- dbus_error_init(&err);
+ dbus_server_set_data(server, server_slot, server, NULL);
- conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ dbus_server_set_watch_functions(server, add_server, remove_server,
+ server_toggled, server, NULL);
- if (dbus_error_is_set(&err)) {
- error("Can't connect to system message bus: %s", err.message);
- dbus_error_free(&err);
- return NULL;
- }
+ dbus_server_set_timeout_functions(server, add_timeout, remove_timeout,
+ timeout_toggled, server, NULL);
+#endif
+}
+void setup_dbus_with_main_loop(DBusConnection *conn)
+{
#ifdef HAVE_DBUS_GLIB
dbus_connection_setup_with_g_main(conn, NULL);
#else
@@ -549,6 +628,26 @@ DBusConnection *init_dbus(const char *name,
dbus_connection_set_dispatch_status_function(conn, dispatch_status_cb,
conn, NULL);
#endif
+}
+
+DBusConnection *init_dbus(const char *name,
+ void (*disconnect_cb)(void *), void *user_data)
+{
+ struct disconnect_data *dc_data;
+ DBusConnection *conn;
+ DBusError err;
+
+ dbus_error_init(&err);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+
+ if (dbus_error_is_set(&err)) {
+ error("Can't connect to system message bus: %s", err.message);
+ dbus_error_free(&err);
+ return NULL;
+ }
+
+ setup_dbus_with_main_loop(conn);
if (name) {
dbus_error_init(&err);
@@ -589,6 +688,28 @@ DBusConnection *init_dbus(const char *name,
return conn;
}
+DBusConnection *init_dbus_direct(const char *address)
+{
+ DBusConnection *conn;
+ DBusError err;
+
+ dbus_error_init(&err);
+
+ conn = dbus_connection_open(address, &err);
+
+ if (dbus_error_is_set(&err)) {
+ error("Can't connect to message server: %s", err.message);
+ dbus_error_free(&err);
+ return NULL;
+ }
+
+ setup_dbus_with_main_loop(conn);
+
+ dbus_connection_set_exit_on_disconnect(conn, FALSE);
+
+ return conn;
+}
+
DBusConnection *dbus_bus_system_setup_with_main_loop(const char *name,
void (*disconnect_cb)(void *), void *user_data)
{
diff --git a/common/dbus.h b/common/dbus.h
index 26ccb6e0..23448cf7 100644
--- a/common/dbus.h
+++ b/common/dbus.h
@@ -26,9 +26,14 @@
#include <dbus/dbus.h>
+void setup_dbus_server_with_main_loop(DBusServer *server);
+void setup_dbus_with_main_loop(DBusConnection *conn);
+
DBusConnection *init_dbus(const char *name,
void (*disconnect_cb)(void *), void *user_data);
+DBusConnection *init_dbus_direct(const char *address);
+
DBusConnection *dbus_bus_system_setup_with_main_loop(const char *name,
void (*disconnect_cb)(void *), void *user_data);
diff --git a/daemon/echo.c b/daemon/echo.c
index d6a852e1..65d521a9 100644
--- a/daemon/echo.c
+++ b/daemon/echo.c
@@ -49,7 +49,8 @@ struct auth_data {
char *address;
};
-static gboolean session_event(GIOChannel *chan, GIOCondition cond, gpointer data)
+static gboolean session_event(GIOChannel *chan,
+ GIOCondition cond, gpointer data)
{
unsigned char buf[672];
gsize len, written;
@@ -75,7 +76,7 @@ static void cancel_authorization(DBusConnection *conn, const char *address)
info("Canceling authorization for %s", address);
msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
- "org.bluez.Database", "CancelAuthorizationRequest");
+ "org.bluez.Database", "CancelAuthorizationRequest");
if (!msg) {
error("Allocation of method message failed");
return;
@@ -104,8 +105,9 @@ static void authorization_callback(DBusPendingCall *call, void *data)
dbus_error_free(&err);
} else {
info("Accepting incoming connection");
- g_io_add_watch(auth->io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- session_event, NULL);
+ g_io_add_watch(auth->io,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ session_event, NULL);
}
g_io_channel_unref(auth->io);
@@ -169,7 +171,8 @@ static int request_authorization(DBusConnection *conn,
return 0;
}
-static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data)
+static gboolean connect_event(GIOChannel *chan,
+ GIOCondition cond, gpointer data)
{
DBusConnection *conn = data;
GIOChannel *io;
@@ -364,14 +367,10 @@ static void sig_term(int sig)
g_main_loop_quit(main_loop);
}
-static void sig_hup(int sig)
-{
-}
-
int main(int argc, char *argv[])
{
- DBusConnection *system_bus;
- GIOChannel *server_io;
+ DBusConnection *conn;
+ GIOChannel *io;
struct sigaction sa;
char *addr;
@@ -382,8 +381,6 @@ int main(int argc, char *argv[])
sa.sa_handler = sig_term;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
- sa.sa_handler = sig_hup;
- sigaction(SIGHUP, &sa, NULL);
sa.sa_handler = SIG_IGN;
sigaction(SIGCHLD, &sa, NULL);
@@ -397,31 +394,31 @@ int main(int argc, char *argv[])
main_loop = g_main_loop_new(NULL, FALSE);
- system_bus = init_dbus(NULL, NULL, NULL);
- if (!system_bus) {
+ conn = init_dbus_direct(addr);
+ if (!conn) {
error("Connection to system bus failed");
g_main_loop_unref(main_loop);
exit(1);
}
- server_io = setup_rfcomm(system_bus, 23);
- if (!server_io) {
+ io = setup_rfcomm(conn, 23);
+ if (!io) {
error("Creation of server channel failed");
- dbus_connection_unref(system_bus);
+ dbus_connection_unref(conn);
g_main_loop_unref(main_loop);
exit(1);
}
- setup_sdp(system_bus, 23);
+ setup_sdp(conn, 23);
if (argc > 1 && !strcmp(argv[1], "-s"))
- register_standalone(system_bus);
+ register_standalone(conn);
g_main_loop_run(main_loop);
- g_io_channel_unref(server_io);
+ g_io_channel_unref(io);
- dbus_connection_unref(system_bus);
+ dbus_connection_unref(conn);
g_main_loop_unref(main_loop);
diff --git a/hcid/server.c b/hcid/server.c
index e055efff..57241909 100644
--- a/hcid/server.c
+++ b/hcid/server.c
@@ -33,6 +33,8 @@
static DBusHandlerResult message_handler(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ debug("Incoming message %p", conn);
+
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -55,6 +57,7 @@ static void handle_connection(DBusServer *server, DBusConnection *conn, void *da
dbus_connection_ref(conn);
//dbus_connection_setup_with_g_main(conn, NULL);
+ setup_dbus_with_main_loop(conn);
}
static DBusServer *server = NULL;
@@ -85,6 +88,7 @@ void init_local_server(void)
dbus_free(address);
//dbus_server_setup_with_g_main(server, NULL);
+ setup_dbus_server_with_main_loop(server);
dbus_server_set_new_connection_function(server, handle_connection,
NULL, NULL);