From 5babbaafb26ac4f83db0d8bca53006a843472b8f Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Fri, 12 Jun 2009 07:16:05 +0300 Subject: daemon: Implement the DBus server lookup service. --- src/daemon/server-lookup.c | 277 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 src/daemon/server-lookup.c (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c new file mode 100644 index 00000000..867c3a1c --- /dev/null +++ b/src/daemon/server-lookup.c @@ -0,0 +1,277 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Tanu Kaskinen + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio 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 Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include +#include +#include + +#include "server-lookup.h" + +struct pa_dbusobj_server_lookup { + pa_dbus_connection *conn; + pa_bool_t path_registered; + pa_daemon_conf_server_type_t server_type; +}; + +static const char introspection[] = + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "" + " \n" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +static void unregister_cb(DBusConnection *conn, void *user_data) { + pa_dbusobj_server_lookup *sl = user_data; + + pa_assert(sl); + pa_assert(sl->path_registered); + + sl->path_registered = FALSE; +} + +static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + const char *i = introspection; + DBusMessage *reply = NULL; + + pa_assert(conn); + pa_assert(msg); + + if (!(reply = dbus_message_new_method_return(msg))) + goto fail; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &i, DBUS_TYPE_INVALID)) + goto fail; + + if (!dbus_connection_send(conn, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + +fail: + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +/* Caller frees the string. */ +static char *get_dbus_server_from_type(pa_daemon_conf_server_type_t server_type) { + char *server_string = NULL; + char *runtime_dir = NULL; + + switch (server_type) { + case PA_SERVER_TYPE_USER: + runtime_dir = pa_get_runtime_dir(); + + if (!runtime_dir) + return NULL; + + server_string = pa_sprintf_malloc("unix:path=%s/dbus_socket", runtime_dir); + break; + + case PA_SERVER_TYPE_SYSTEM: + server_string = pa_xstrdup("unix:path=/var/run/pulse/dbus_socket"); + break; + + case PA_SERVER_TYPE_NONE: + server_string = pa_xnew0(char, 1); + break; + + default: + pa_assert_not_reached(); + } + + return server_string; +} + +static DBusHandlerResult handle_get_dbus_servers(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + DBusMessage *reply = NULL; + pa_client_conf *conf = NULL; + char *server_string = NULL; + + pa_assert(conn); + pa_assert(msg); + pa_assert(sl); + + conf = pa_client_conf_new(); + + if (pa_client_conf_load(conf, NULL) < 0) { + if (!(reply = dbus_message_new_error(msg, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf."))) + goto fail; + if (!dbus_connection_send(conn, reply, NULL)) + goto oom; + return DBUS_HANDLER_RESULT_HANDLED; + } + + server_string = pa_xstrdup(conf->default_dbus_server); + + pa_client_conf_free(conf); + + if (!server_string) { + if (!(server_string = get_dbus_server_from_type(sl->server_type))) { + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "get_dbus_server_from_type() failed."))) + goto fail; + if (!dbus_connection_send(conn, reply, NULL)) + goto oom; + return DBUS_HANDLER_RESULT_HANDLED; + } + } + + if (!(reply = dbus_message_new_method_return(msg))) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &server_string, DBUS_TYPE_INVALID)) + goto fail; + + if (!dbus_connection_send(conn, reply, NULL)) + goto oom; + + pa_log("Sent reply with server_string '%s'.", server_string); + + pa_xfree(server_string); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + +fail: + if (conf) + pa_client_conf_free(conf); + + pa_xfree(server_string); + + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + if (conf) + pa_client_conf_free(conf); + + pa_xfree(server_string); + + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void *user_data) { + pa_dbusobj_server_lookup *sl = user_data; + + pa_assert(conn); + pa_assert(msg); + pa_assert(sl); + + /* pa_log("Got message! type = %s path = %s iface = %s member = %s dest = %s", dbus_message_type_to_string(dbus_message_get_type(msg)), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), dbus_message_get_destination(msg)); */ + + if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) + return handle_introspect(conn, msg, sl); + + if (dbus_message_is_method_call(msg, "org.pulseaudio.ServerLookup", "GetDBusServers")) + return handle_get_dbus_servers(conn, msg, sl); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusObjectPathVTable vtable = { + .unregister_function = unregister_cb, + .message_function = message_cb, + .dbus_internal_pad1 = NULL, + .dbus_internal_pad2 = NULL, + .dbus_internal_pad3 = NULL, + .dbus_internal_pad4 = NULL +}; + +pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c, pa_daemon_conf_server_type_t server_type) { + pa_dbusobj_server_lookup *sl; + DBusError error; + + dbus_error_init(&error); + + sl = pa_xnew(pa_dbusobj_server_lookup, 1); + sl->path_registered = FALSE; + sl->server_type = server_type; + + if (!(sl->conn = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { + pa_log("Unable to contact D-Bus: %s: %s", error.name, error.message); + goto fail; + } + + if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl->conn), "/org/pulseaudio/server_lookup", &vtable, sl)) { + pa_log("dbus_connection_register_object_path() failed for /org/pulseaudio/server_lookup."); + goto fail; + } + + sl->path_registered = TRUE; + + return sl; + +fail: + dbus_error_free(&error); + + pa_dbusobj_server_lookup_free(sl); + + return NULL; +} + +void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup *sl) { + pa_assert(sl); + + if (sl->path_registered) { + pa_assert(sl->conn); + if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl->conn), "/org/pulseaudio/server_lookup")) + pa_log_debug("dbus_connection_unregister_object_path() failed for /org/pulseaudio/server_lookup."); + } + + if (sl->conn) + pa_dbus_connection_unref(sl->conn); + + pa_xfree(sl); +} \ No newline at end of file -- cgit From c8d819a5adbe32e14d7f03a252bca6f7df01d795 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 16 Jun 2009 19:03:22 +0300 Subject: dbus-protocol: Connection handling for local connections. --- src/daemon/server-lookup.c | 69 ++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 48 deletions(-) (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c index 867c3a1c..b53fda76 100644 --- a/src/daemon/server-lookup.c +++ b/src/daemon/server-lookup.c @@ -28,16 +28,18 @@ #include #include +#include #include +#include #include #include #include "server-lookup.h" struct pa_dbusobj_server_lookup { + pa_core *core; pa_dbus_connection *conn; pa_bool_t path_registered; - pa_daemon_conf_server_type_t server_type; }; static const char introspection[] = @@ -46,7 +48,7 @@ static const char introspection[] = " \n" " " - " " + " " " " " " " " @@ -99,40 +101,10 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } -/* Caller frees the string. */ -static char *get_dbus_server_from_type(pa_daemon_conf_server_type_t server_type) { - char *server_string = NULL; - char *runtime_dir = NULL; - - switch (server_type) { - case PA_SERVER_TYPE_USER: - runtime_dir = pa_get_runtime_dir(); - - if (!runtime_dir) - return NULL; - - server_string = pa_sprintf_malloc("unix:path=%s/dbus_socket", runtime_dir); - break; - - case PA_SERVER_TYPE_SYSTEM: - server_string = pa_xstrdup("unix:path=/var/run/pulse/dbus_socket"); - break; - - case PA_SERVER_TYPE_NONE: - server_string = pa_xnew0(char, 1); - break; - - default: - pa_assert_not_reached(); - } - - return server_string; -} - -static DBusHandlerResult handle_get_dbus_servers(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { +static DBusHandlerResult handle_get_dbus_address(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { DBusMessage *reply = NULL; pa_client_conf *conf = NULL; - char *server_string = NULL; + char *address = NULL; pa_assert(conn); pa_assert(msg); @@ -148,12 +120,13 @@ static DBusHandlerResult handle_get_dbus_servers(DBusConnection *conn, DBusMessa return DBUS_HANDLER_RESULT_HANDLED; } - server_string = pa_xstrdup(conf->default_dbus_server); - pa_client_conf_free(conf); - if (!server_string) { - if (!(server_string = get_dbus_server_from_type(sl->server_type))) { + if (conf->default_dbus_server) { + if (!(address = dbus_address_escape_value(conf->default_dbus_server))) + goto oom; + } else { + if (!(address = pa_get_dbus_address_from_server_type(sl->core->server_type))) { if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "get_dbus_server_from_type() failed."))) goto fail; if (!dbus_connection_send(conn, reply, NULL)) @@ -165,15 +138,15 @@ static DBusHandlerResult handle_get_dbus_servers(DBusConnection *conn, DBusMessa if (!(reply = dbus_message_new_method_return(msg))) goto oom; - if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &server_string, DBUS_TYPE_INVALID)) + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) goto fail; if (!dbus_connection_send(conn, reply, NULL)) goto oom; - pa_log("Sent reply with server_string '%s'.", server_string); + pa_log_debug("handle_get_dbus_address(): Sent reply with address '%s'.", address); - pa_xfree(server_string); + pa_xfree(address); dbus_message_unref(reply); @@ -183,7 +156,7 @@ fail: if (conf) pa_client_conf_free(conf); - pa_xfree(server_string); + pa_xfree(address); if (reply) dbus_message_unref(reply); @@ -194,7 +167,7 @@ oom: if (conf) pa_client_conf_free(conf); - pa_xfree(server_string); + pa_xfree(address); if (reply) dbus_message_unref(reply); @@ -214,8 +187,8 @@ static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) return handle_introspect(conn, msg, sl); - if (dbus_message_is_method_call(msg, "org.pulseaudio.ServerLookup", "GetDBusServers")) - return handle_get_dbus_servers(conn, msg, sl); + if (dbus_message_is_method_call(msg, "org.pulseaudio.ServerLookup", "GetDBusAddress")) + return handle_get_dbus_address(conn, msg, sl); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -229,15 +202,15 @@ static DBusObjectPathVTable vtable = { .dbus_internal_pad4 = NULL }; -pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c, pa_daemon_conf_server_type_t server_type) { +pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c) { pa_dbusobj_server_lookup *sl; DBusError error; dbus_error_init(&error); sl = pa_xnew(pa_dbusobj_server_lookup, 1); + sl->core = c; sl->path_registered = FALSE; - sl->server_type = server_type; if (!(sl->conn = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { pa_log("Unable to contact D-Bus: %s: %s", error.name, error.message); @@ -274,4 +247,4 @@ void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup *sl) { pa_dbus_connection_unref(sl->conn); pa_xfree(sl); -} \ No newline at end of file +} -- cgit From 123c6a3c6ffc9903c0855e38445fc3b6588311ce Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Fri, 19 Jun 2009 10:28:08 +0300 Subject: dbus-common: Implement infrastructure for registering D-Bus objects on all client connections and for receiving method calls from clients. --- src/daemon/server-lookup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c index b53fda76..2d2d8ce6 100644 --- a/src/daemon/server-lookup.c +++ b/src/daemon/server-lookup.c @@ -48,7 +48,7 @@ static const char introspection[] = " \n" " " - " " + " " " " " " " " @@ -101,7 +101,7 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } -static DBusHandlerResult handle_get_dbus_address(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { +static DBusHandlerResult handle_get_address(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { DBusMessage *reply = NULL; pa_client_conf *conf = NULL; char *address = NULL; @@ -187,8 +187,8 @@ static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) return handle_introspect(conn, msg, sl); - if (dbus_message_is_method_call(msg, "org.pulseaudio.ServerLookup", "GetDBusAddress")) - return handle_get_dbus_address(conn, msg, sl); + if (dbus_message_is_method_call(msg, "org.pulseaudio.ServerLookup", "GetAddress")) + return handle_get_address(conn, msg, sl); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -- cgit From 3c6a0acc98a8326ad7a19c29005bba353396a88b Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Fri, 19 Jun 2009 15:17:57 +0300 Subject: dbus-protocol: Implement TCP server startup. --- src/daemon/server-lookup.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c index 2d2d8ce6..33d6b24c 100644 --- a/src/daemon/server-lookup.c +++ b/src/daemon/server-lookup.c @@ -120,14 +120,11 @@ static DBusHandlerResult handle_get_address(DBusConnection *conn, DBusMessage *m return DBUS_HANDLER_RESULT_HANDLED; } - pa_client_conf_free(conf); - if (conf->default_dbus_server) { - if (!(address = dbus_address_escape_value(conf->default_dbus_server))) - goto oom; + address = pa_xstrdup(conf->default_dbus_server); } else { if (!(address = pa_get_dbus_address_from_server_type(sl->core->server_type))) { - if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "get_dbus_server_from_type() failed."))) + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "PulseAudio internal error: get_dbus_server_from_type() failed."))) goto fail; if (!dbus_connection_send(conn, reply, NULL)) goto oom; @@ -144,10 +141,8 @@ static DBusHandlerResult handle_get_address(DBusConnection *conn, DBusMessage *m if (!dbus_connection_send(conn, reply, NULL)) goto oom; - pa_log_debug("handle_get_dbus_address(): Sent reply with address '%s'.", address); - + pa_client_conf_free(conf); pa_xfree(address); - dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; -- cgit From 6e2fec05ddd38fa460276202ca2f4ecf68761ed0 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 30 Jun 2009 15:21:20 +0300 Subject: server-lookup: Update the D-Bus identifiers to be versioned. --- src/daemon/server-lookup.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c index 33d6b24c..7c80d677 100644 --- a/src/daemon/server-lookup.c +++ b/src/daemon/server-lookup.c @@ -36,6 +36,9 @@ #include "server-lookup.h" +#define OBJECT_PATH "/org/pulseaudio1/server_lookup" +#define INTERFACE "org.pulseaudio.ServerLookup1" + struct pa_dbusobj_server_lookup { pa_core *core; pa_dbus_connection *conn; @@ -47,7 +50,7 @@ static const char introspection[] = "" " \n" - " " + " " " " " " " " @@ -182,7 +185,7 @@ static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) return handle_introspect(conn, msg, sl); - if (dbus_message_is_method_call(msg, "org.pulseaudio.ServerLookup", "GetAddress")) + if (dbus_message_is_method_call(msg, INTERFACE, "GetAddress")) return handle_get_address(conn, msg, sl); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -212,8 +215,8 @@ pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c) { goto fail; } - if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl->conn), "/org/pulseaudio/server_lookup", &vtable, sl)) { - pa_log("dbus_connection_register_object_path() failed for /org/pulseaudio/server_lookup."); + if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl->conn), OBJECT_PATH, &vtable, sl)) { + pa_log("dbus_connection_register_object_path() failed for " OBJECT_PATH "."); goto fail; } @@ -234,8 +237,8 @@ void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup *sl) { if (sl->path_registered) { pa_assert(sl->conn); - if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl->conn), "/org/pulseaudio/server_lookup")) - pa_log_debug("dbus_connection_unregister_object_path() failed for /org/pulseaudio/server_lookup."); + if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl->conn), OBJECT_PATH)) + pa_log_debug("dbus_connection_unregister_object_path() failed for " OBJECT_PATH "."); } if (sl->conn) -- cgit From 5c7952e4fa5e560f64255ef173c3e6570bee433a Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Fri, 3 Jul 2009 02:49:07 +0300 Subject: dbus: Implement the Name property of the core object. --- src/daemon/server-lookup.c | 414 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 344 insertions(+), 70 deletions(-) (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c index 7c80d677..ebacc099 100644 --- a/src/daemon/server-lookup.c +++ b/src/daemon/server-lookup.c @@ -37,7 +37,7 @@ #include "server-lookup.h" #define OBJECT_PATH "/org/pulseaudio1/server_lookup" -#define INTERFACE "org.pulseaudio.ServerLookup1" +#define INTERFACE "org.PulseAudio.ServerLookup1" struct pa_dbusobj_server_lookup { pa_core *core; @@ -50,17 +50,31 @@ static const char introspection[] = "" " \n" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"; static void unregister_cb(DBusConnection *conn, void *user_data) { pa_dbusobj_server_lookup *sl = user_data; @@ -72,105 +86,352 @@ static void unregister_cb(DBusConnection *conn, void *user_data) { } static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED; const char *i = introspection; DBusMessage *reply = NULL; pa_assert(conn); pa_assert(msg); - if (!(reply = dbus_message_new_method_return(msg))) - goto fail; + if (!(reply = dbus_message_new_method_return(msg))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &i, DBUS_TYPE_INVALID)) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } - if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &i, DBUS_TYPE_INVALID)) - goto fail; +finish: + if (reply) + dbus_message_unref(reply); - if (!dbus_connection_send(conn, reply, NULL)) - goto oom; + return r; +} - dbus_message_unref(reply); +enum get_address_result_t { + SUCCESS, + FAILED_TO_LOAD_CLIENT_CONF, + SERVER_FROM_TYPE_FAILED +}; - return DBUS_HANDLER_RESULT_HANDLED; +/* Caller frees the returned address. */ +static enum get_address_result_t get_address(pa_server_type_t server_type, char **address) { + enum get_address_result_t r = SUCCESS; + pa_client_conf *conf = pa_client_conf_new(); -fail: - if (reply) - dbus_message_unref(reply); + *address = NULL; - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + if (pa_client_conf_load(conf, NULL) < 0) { + r = FAILED_TO_LOAD_CLIENT_CONF; + goto finish; + } -oom: - if (reply) - dbus_message_unref(reply); + if (conf->default_dbus_server) + *address = pa_xstrdup(conf->default_dbus_server); + else if (!(*address = pa_get_dbus_address_from_server_type(server_type))) { + r = SERVER_FROM_TYPE_FAILED; + goto finish; + } - return DBUS_HANDLER_RESULT_NEED_MEMORY; +finish: + pa_client_conf_free(conf); + return r; } static DBusHandlerResult handle_get_address(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED; DBusMessage *reply = NULL; - pa_client_conf *conf = NULL; char *address = NULL; + DBusMessageIter msg_iter; + DBusMessageIter variant_iter; pa_assert(conn); pa_assert(msg); pa_assert(sl); - conf = pa_client_conf_new(); + switch (get_address(sl->core->server_type, &address)) { + case SUCCESS: + if (!(reply = dbus_message_new_method_return(msg))) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + dbus_message_iter_init_append(reply, &msg_iter); + if (!dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_VARIANT, "s", &variant_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &address)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_close_container(&msg_iter, &variant_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + + case FAILED_TO_LOAD_CLIENT_CONF: + if (!(reply = dbus_message_new_error(msg, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf."))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + + case SERVER_FROM_TYPE_FAILED: + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "PulseAudio internal error: get_dbus_server_from_type() failed."))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + + default: + pa_assert_not_reached(); + } - if (pa_client_conf_load(conf, NULL) < 0) { - if (!(reply = dbus_message_new_error(msg, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf."))) - goto fail; - if (!dbus_connection_send(conn, reply, NULL)) - goto oom; - return DBUS_HANDLER_RESULT_HANDLED; - } - - if (conf->default_dbus_server) { - address = pa_xstrdup(conf->default_dbus_server); - } else { - if (!(address = pa_get_dbus_address_from_server_type(sl->core->server_type))) { - if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "PulseAudio internal error: get_dbus_server_from_type() failed."))) - goto fail; - if (!dbus_connection_send(conn, reply, NULL)) - goto oom; - return DBUS_HANDLER_RESULT_HANDLED; +finish: + pa_xfree(address); + if (reply) + dbus_message_unref(reply); + + return r; +} + +static DBusHandlerResult handle_get(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED; + const char* interface; + const char* property; + DBusMessage *reply = NULL; + + pa_assert(conn); + pa_assert(msg); + pa_assert(sl); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) { + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; } - if (!(reply = dbus_message_new_method_return(msg))) - goto oom; + if (*interface && !pa_streq(interface, INTERFACE)) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } - if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) - goto fail; + if (!pa_streq(property, "Address")) { + if (!(reply = dbus_message_new_error_printf(msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s: No such property", property))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + } - if (!dbus_connection_send(conn, reply, NULL)) - goto oom; + r = handle_get_address(conn, msg, sl); - pa_client_conf_free(conf); - pa_xfree(address); - dbus_message_unref(reply); +finish: + if (reply) + dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_HANDLED; + return r; +} -fail: - if (conf) - pa_client_conf_free(conf); +static DBusHandlerResult handle_set(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED; + const char* interface; + const char* property; + DBusMessage *reply = NULL; - pa_xfree(address); + pa_assert(conn); + pa_assert(msg); + pa_assert(sl); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) { + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + } + + if (*interface && !pa_streq(interface, INTERFACE)) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + + if (!pa_streq(property, "Address")) { + if (!(reply = dbus_message_new_error_printf(msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s: No such property", property))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + } + + if (!(reply = dbus_message_new_error_printf(msg, DBUS_ERROR_ACCESS_DENIED, "%s: Property not settable", property))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; +finish: if (reply) dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + return r; +} -oom: - if (conf) - pa_client_conf_free(conf); +static DBusHandlerResult handle_get_all(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) { + DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED; + DBusMessage *reply = NULL; + const char *property = "Address"; + char *interface = NULL; + char *address = NULL; + DBusMessageIter msg_iter; + DBusMessageIter dict_iter; + DBusMessageIter dict_entry_iter; + DBusMessageIter variant_iter; - pa_xfree(address); + pa_assert(conn); + pa_assert(msg); + pa_assert(sl); + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID)) { + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + } + + switch (get_address(sl->core->server_type, &address)) { + case SUCCESS: + if (!(reply = dbus_message_new_method_return(msg))) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + dbus_message_iter_init_append(reply, &msg_iter); + if (!dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &property)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_open_container(&dict_entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &address)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_close_container(&dict_entry_iter, &variant_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_close_container(&dict_iter, &dict_entry_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_message_iter_close_container(&msg_iter, &dict_iter)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + + case FAILED_TO_LOAD_CLIENT_CONF: + if (!(reply = dbus_message_new_error(msg, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf."))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + + case SERVER_FROM_TYPE_FAILED: + if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "PulseAudio internal error: get_dbus_server_from_type() failed."))) { + r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto finish; + } + if (!dbus_connection_send(conn, reply, NULL)) { + r = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto finish; + } + r = DBUS_HANDLER_RESULT_HANDLED; + goto finish; + + default: + pa_assert_not_reached(); + } + +finish: + pa_xfree(address); if (reply) dbus_message_unref(reply); - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return r; } static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -182,11 +443,24 @@ static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void /* pa_log("Got message! type = %s path = %s iface = %s member = %s dest = %s", dbus_message_type_to_string(dbus_message_get_type(msg)), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), dbus_message_get_destination(msg)); */ - if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) + if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE, "Introspect") || + (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "Introspect"))) return handle_introspect(conn, msg, sl); - if (dbus_message_is_method_call(msg, INTERFACE, "GetAddress")) - return handle_get_address(conn, msg, sl); + if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "Get") || + (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "Get"))) + return handle_get(conn, msg, sl); + + if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "Set") || + (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "Set"))) + return handle_set(conn, msg, sl); + + if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "GetAll") || + (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "GetAll"))) + return handle_get_all(conn, msg, sl); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -- cgit From 9347e90fed732dac619bb88f6518c344e7436447 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 21 Jul 2009 00:02:27 +0300 Subject: Finish the Core dbus interface. --- src/daemon/server-lookup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/daemon/server-lookup.c') diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c index ebacc099..45796e72 100644 --- a/src/daemon/server-lookup.c +++ b/src/daemon/server-lookup.c @@ -30,13 +30,13 @@ #include #include -#include #include #include +#include #include "server-lookup.h" -#define OBJECT_PATH "/org/pulseaudio1/server_lookup" +#define OBJECT_PATH "/org/pulseaudio/server_lookup1" #define INTERFACE "org.PulseAudio.ServerLookup1" struct pa_dbusobj_server_lookup { -- cgit