From ee6b2930a0519021232f92f615f6a8fd9cd61805 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Jan 2007 17:56:00 +0000 Subject: Add more D-Bus helpers --- common/Makefile.am | 1 + common/dbus-helper.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++ common/dbus-helper.h | 51 +++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 common/dbus-helper.c create mode 100644 common/dbus-helper.h diff --git a/common/Makefile.am b/common/Makefile.am index f4868562..a92ff9a3 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -23,6 +23,7 @@ noinst_LIBRARIES = libhelper.a libhelper_a_SOURCES = oui.h oui.c dbus.h dbus.c \ textfile.h textfile.c logging.h logging.c \ + dbus-helper.h dbus-helper.c \ sdp-xml.h sdp-xml.c $(sdp_sources) \ notify.h $(notify_sources) \ glib-ectomy.h $(glib_sources) diff --git a/common/dbus-helper.c b/common/dbus-helper.c new file mode 100644 index 00000000..bb6e7102 --- /dev/null +++ b/common/dbus-helper.c @@ -0,0 +1,175 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2007 Marcel Holtmann + * + * + * 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 +#endif + +#include +#include + +#include + +#include "logging.h" + +#include "dbus-helper.h" + +struct generic_data { + void *user_data; + DBusObjectPathUnregisterFunction unregister_function; + const char *interface; + DBusMethodVTable *methods; + char *introspect; +}; + +DBusHandlerResult dbus_connection_send_and_unref(DBusConnection *connection, + DBusMessage *message) +{ + if (message) { + dbus_connection_send(connection, message, NULL); + dbus_message_unref(message); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult introspect(DBusConnection *connection, + DBusMessage *message, struct generic_data *data) +{ + DBusMessage *reply; + + if (dbus_message_has_signature(message, + DBUS_TYPE_INVALID_AS_STRING) == FALSE) { + error("Unexpected signature to introspect call"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!data->introspect) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + reply = dbus_message_new_method_return(message); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect, + DBUS_TYPE_INVALID); + + return dbus_connection_send_and_unref(connection, reply); +} + +static void generic_unregister(DBusConnection *connection, void *user_data) +{ + struct generic_data *data = user_data; + + if (data->unregister_function) + data->unregister_function(connection, data->user_data); + + free(data); +} + +static DBusHandlerResult generic_message(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct generic_data *data = user_data; + DBusMethodVTable *current; + + if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, + "Introspect") == TRUE) + return introspect(connection, message, data); + + for (current = data->methods; + current->name && current->message_function; current++) { + if (dbus_message_is_method_call(message, + data->interface, current->name) == FALSE) + continue; + + if (dbus_message_has_signature(message, + current->signature) == TRUE) + return current->message_function(connection, + message, data->user_data); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusObjectPathVTable generic_table = { + .unregister_function = generic_unregister, + .message_function = generic_message, +}; + +dbus_bool_t dbus_connection_create_object_path(DBusConnection *connection, + const char *path, void *user_data, + DBusObjectPathUnregisterFunction function) +{ + struct generic_data *data; + + data = malloc(sizeof(*data)); + if (!data) + return FALSE; + + memset(data, 0, sizeof(*data)); + + data->user_data = user_data; + data->unregister_function = function; + + if (dbus_connection_register_object_path(connection, path, + &generic_table, data) == FALSE) { + free(data); + return FALSE; + } + + return TRUE; +} + +dbus_bool_t dbus_connection_destroy_object_path(DBusConnection *connection, + const char *path) +{ + return dbus_connection_unregister_object_path(connection, path); +} + +static char simple_xml[] = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE ""; + +dbus_bool_t dbus_connection_register_interface(DBusConnection *connection, + const char *path, const char *interface, + DBusMethodVTable *methods, + DBusPropertyVTable *properties) +{ + struct generic_data *data; + DBusMethodVTable *current; + + if (dbus_connection_get_object_path_data(connection, path, + (void *) &data) == FALSE) + return FALSE; + + data->interface = interface; + data->methods = methods; + + for (current = data->methods; current->name; current++) { + debug("Adding introspection data for %s.%s", + interface, current->name); + } + + data->introspect = simple_xml; + + return TRUE; +} diff --git a/common/dbus-helper.h b/common/dbus-helper.h new file mode 100644 index 00000000..a4e405ff --- /dev/null +++ b/common/dbus-helper.h @@ -0,0 +1,51 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2007 Marcel Holtmann + * + * + * 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 + * + */ + +DBusHandlerResult dbus_connection_send_and_unref(DBusConnection *connection, + DBusMessage *message); + +dbus_bool_t dbus_connection_create_object_path(DBusConnection *connection, + const char *path, void *user_data, + DBusObjectPathUnregisterFunction function); + +dbus_bool_t dbus_connection_destroy_object_path(DBusConnection *connection, + const char *path); + +typedef struct DBusMethodVTable DBusMethodVTable; + +struct DBusMethodVTable { + const char *name; + DBusObjectPathMessageFunction message_function; + const char *signature; + const char *reply; +}; + +typedef struct DBusPropertyVTable DBusPropertyVTable; + +struct DBusPropertyVTable { +}; + +dbus_bool_t dbus_connection_register_interface(DBusConnection *connection, + const char *path, const char *interface, + DBusMethodVTable *methods, + DBusPropertyVTable *properties); -- cgit