diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-05-08 20:23:45 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-05-08 20:23:45 +0000 |
commit | e7d668ac9e813bc9922ee7d771848bd8822d5d1f (patch) | |
tree | 34e2fc7b1c064beaa52e5e05e9278be458be9fba /common | |
parent | 44a204a75880c342c3ac9066072f102f773a539a (diff) |
Move D-Bus watch functions into libgdbus
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 6 | ||||
-rw-r--r-- | common/dbus-helper.h | 14 | ||||
-rw-r--r-- | common/dbus.c | 391 | ||||
-rw-r--r-- | common/dbus.h | 49 |
4 files changed, 16 insertions, 444 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index a90df3247..5352d34f3 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -2,9 +2,9 @@ noinst_LIBRARIES = libhelper.a libhelper_a_SOURCES = oui.h oui.c textfile.h textfile.c \ - logging.h logging.c error.h error.c dbus.h dbus.c \ - dbus-helper.h dbus-helper.c glib-helper.h glib-helper.c \ - sdp-xml.h sdp-xml.c sdp-glib.c + logging.h logging.c error.h error.c \ + dbus-helper.h dbus-helper.c \ + glib-helper.h glib-helper.c sdp-xml.h sdp-xml.c sdp-glib.c noinst_PROGRAMS = test_textfile diff --git a/common/dbus-helper.h b/common/dbus-helper.h index 57c3d09b4..6c3c3a890 100644 --- a/common/dbus-helper.h +++ b/common/dbus-helper.h @@ -20,8 +20,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ + #include <stdarg.h> -#include <dbus.h> +#include <dbus/dbus.h> #define DBUS_TYPE_STRING_ARRAY_AS_STRING (DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING) #define DBUS_TYPE_BYTE_ARRAY_AS_STRING (DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING) @@ -93,3 +94,14 @@ dbus_bool_t dbus_connection_emit_property_changed(DBusConnection *conn, const char *interface, const char *name, int type, void *value); + +static inline DBusHandlerResult send_message_and_unref(DBusConnection *conn, + DBusMessage *msg) +{ + if (msg) { + dbus_connection_send(conn, msg, NULL); + dbus_message_unref(msg); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} diff --git a/common/dbus.c b/common/dbus.c deleted file mode 100644 index 4ea56c9f6..000000000 --- a/common/dbus.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org> - * - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <stdint.h> - -#include <glib.h> - -#include <dbus/dbus.h> - -#ifdef NEED_DBUS_WATCH_GET_UNIX_FD -#define dbus_watch_get_unix_fd dbus_watch_get_fd -#endif - -#ifdef HAVE_DBUS_GLIB -#include <dbus/dbus-glib-lowlevel.h> -#endif - -#include "dbus.h" -#include "logging.h" - -static guint listener_id = 0; -static GSList *name_listeners = NULL; - -struct name_callback { - name_cb_t func; - void *user_data; - guint id; -}; - -struct name_data { - DBusConnection *connection; - char *name; - GSList *callbacks; -}; - -static struct name_data *name_data_find(DBusConnection *connection, - const char *name) -{ - GSList *current; - - for (current = name_listeners; - current != NULL; current = current->next) { - struct name_data *data = current->data; - - if (name == NULL && data->name == NULL) { - if (connection == data->connection) - return data; - } else { - if (strcmp(name, data->name) == 0) - return data; - } - } - - return NULL; -} - -static struct name_callback *name_callback_find(GSList *callbacks, - name_cb_t func, void *user_data) -{ - GSList *current; - - for (current = callbacks; current != NULL; current = current->next) { - struct name_callback *cb = current->data; - if (cb->func == func && cb->user_data == user_data) - return cb; - } - - return NULL; -} - -static void name_data_call_and_free(struct name_data *data) -{ - GSList *l; - - for (l = data->callbacks; l != NULL; l = l->next) { - struct name_callback *cb = l->data; - if (cb->func) - cb->func(data->name, cb->user_data); - g_free(cb); - } - - g_slist_free(data->callbacks); - g_free(data->name); - g_free(data); -} - -static void name_data_free(struct name_data *data) -{ - GSList *l; - - for (l = data->callbacks; l != NULL; l = l->next) - g_free(l->data); - - g_slist_free(data->callbacks); - g_free(data->name); - g_free(data); -} - -static int name_data_add(DBusConnection *connection, const char *name, - name_cb_t func, void *user_data, guint id) -{ - int first = 1; - struct name_data *data = NULL; - struct name_callback *cb = NULL; - - cb = g_new(struct name_callback, 1); - - cb->func = func; - cb->user_data = user_data; - cb->id = id; - - data = name_data_find(connection, name); - if (data) { - first = 0; - goto done; - } - - data = g_new0(struct name_data, 1); - - data->connection = connection; - data->name = g_strdup(name); - - name_listeners = g_slist_append(name_listeners, data); - -done: - data->callbacks = g_slist_append(data->callbacks, cb); - return first; -} - -static void name_data_remove(DBusConnection *connection, - const char *name, name_cb_t func, void *user_data) -{ - struct name_data *data; - struct name_callback *cb = NULL; - - data = name_data_find(connection, name); - if (!data) - return; - - cb = name_callback_find(data->callbacks, func, user_data); - if (cb) { - data->callbacks = g_slist_remove(data->callbacks, cb); - g_free(cb); - } - - if (!data->callbacks) { - name_listeners = g_slist_remove(name_listeners, data); - name_data_free(data); - } -} - -static gboolean add_match(DBusConnection *connection, const char *name) -{ - DBusError err; - char match_string[128]; - - snprintf(match_string, sizeof(match_string), - "interface=%s,member=NameOwnerChanged,arg0=%s", - DBUS_INTERFACE_DBUS, name); - - dbus_error_init(&err); - - dbus_bus_add_match(connection, match_string, &err); - - if (dbus_error_is_set(&err)) { - error("Adding match rule \"%s\" failed: %s", match_string, - err.message); - dbus_error_free(&err); - return FALSE; - } - - return TRUE; -} - -static gboolean remove_match(DBusConnection *connection, const char *name) -{ - DBusError err; - char match_string[128]; - - snprintf(match_string, sizeof(match_string), - "interface=%s,member=NameOwnerChanged,arg0=%s", - DBUS_INTERFACE_DBUS, name); - - dbus_error_init(&err); - - dbus_bus_remove_match(connection, match_string, &err); - - if (dbus_error_is_set(&err)) { - error("Removing owner match rule for %s failed: %s", - name, err.message); - dbus_error_free(&err); - return FALSE; - } - - return TRUE; -} - -static DBusHandlerResult name_exit_filter(DBusConnection *connection, - DBusMessage *message, void *user_data) -{ - GSList *l; - struct name_data *data; - char *name, *old, *new; - - if (!dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, - "NameOwnerChanged")) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (!dbus_message_get_args(message, NULL, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &old, - DBUS_TYPE_STRING, &new, - DBUS_TYPE_INVALID)) { - error("Invalid arguments for NameOwnerChanged signal"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - /* We are not interested of service creations */ - if (*new != '\0') - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - data = name_data_find(connection, name); - if (!data) { - error("Got NameOwnerChanged signal for %s which has no listeners", name); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - for (l = data->callbacks; l != NULL; l = l->next) { - struct name_callback *cb = l->data; - cb->func(name, cb->user_data); - } - - name_listeners = g_slist_remove(name_listeners, data); - name_data_free(data); - - remove_match(connection, name); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -guint name_listener_add(DBusConnection *connection, const char *name, - name_cb_t func, void *user_data) -{ - int first; - - if (!listener_id) { - if (!dbus_connection_add_filter(connection, - name_exit_filter, NULL, NULL)) { - error("dbus_connection_add_filter() failed"); - return 0; - } - } - - listener_id++; - first = name_data_add(connection, name, func, user_data, listener_id); - /* The filter is already added if this is not the first callback - * registration for the name */ - if (!first) - return listener_id; - - if (name) { - debug("name_listener_add(%s)", name); - - if (!add_match(connection, name)) { - name_data_remove(connection, name, func, user_data); - return 0; - } - } - - return listener_id; -} - -int name_listener_remove(DBusConnection *connection, const char *name, - name_cb_t func, void *user_data) -{ - struct name_data *data; - struct name_callback *cb; - - data = name_data_find(connection, name); - if (!data) { - error("remove_name_listener: no listener for %s", name); - return -1; - } - - cb = name_callback_find(data->callbacks, func, user_data); - if (!cb) { - error("No matching callback found for %s", name); - return -1; - } - - data->callbacks = g_slist_remove(data->callbacks, cb); - g_free(cb); - - /* Don't remove the filter if other callbacks exist */ - if (data->callbacks) - return 0; - - if (name) { - debug("name_listener_remove(%s)", name); - - if (!remove_match(connection, name)) - return -1; - } - - name_data_remove(connection, name, func, user_data); - - return 0; -} - -gboolean name_listener_id_remove(guint id) -{ - struct name_data *data; - struct name_callback *cb; - GSList *ldata, *lcb; - - for (ldata = name_listeners; ldata; ldata = ldata->next) { - data = ldata->data; - for (lcb = data->callbacks; lcb; lcb = lcb->next) { - cb = lcb->data; - if (cb->id == id) - goto remove; - } - } - - return FALSE; - -remove: - data->callbacks = g_slist_remove(data->callbacks, cb); - g_free(cb); - - /* Don't remove the filter if other callbacks exist */ - if (data->callbacks) - return TRUE; - - if (data->name) { - if (!remove_match(data->connection, data->name)) - return FALSE; - } - - name_listeners = g_slist_remove(name_listeners, data); - name_data_free(data); - - return TRUE; -} - -int name_listener_indicate_disconnect(DBusConnection *connection) -{ - struct name_data *data; - - data = name_data_find(connection, NULL); - if (!data) { - error("name_listener_indicate_disconnect: no listener found"); - return -1; - } - - debug("name_listener_indicate_disconnect"); - - name_data_call_and_free(data); - - return 0; -} diff --git a/common/dbus.h b/common/dbus.h deleted file mode 100644 index 5976a479a..000000000 --- a/common/dbus.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org> - * - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __H_BLUEZ_DBUS_H__ -#define __H_BLUEZ_DBUS_H__ - -#include <dbus/dbus.h> -#include <glib.h> - -typedef void (*name_cb_t)(const char *name, void *user_data); - -guint name_listener_add(DBusConnection *connection, const char *name, - name_cb_t func, void *user_data); -int name_listener_remove(DBusConnection *connection, const char *name, - name_cb_t func, void *user_data); -gboolean name_listener_id_remove(guint id); -int name_listener_indicate_disconnect(DBusConnection *connection); - -static inline DBusHandlerResult send_message_and_unref(DBusConnection *conn, DBusMessage *msg) -{ - if (msg) { - dbus_connection_send(conn, msg, NULL); - dbus_message_unref(msg); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -#endif /* __H_BLUEZ_DBUS_H__ */ |