From ec9c575fb8d6d9ee2f929ad6cd70177e35ba9cd3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Jul 2005 01:42:21 +0000 Subject: DBUS: Wrap service resolver Beef up AvahiStringList API a bit git-svn-id: file:///home/lennart/svn/public/avahi/trunk@189 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/strlst.c | 21 ++++++--- avahi-common/strlst.h | 6 +++ avahi-daemon/DBUS-API | 2 +- avahi-daemon/dbus-protocol.c | 110 +++++++++++++++++++++++++++++++++++++++++-- avahi-daemon/dbus-test.py | 3 ++ todo | 2 +- 6 files changed, 133 insertions(+), 11 deletions(-) diff --git a/avahi-common/strlst.c b/avahi-common/strlst.c index d962188..d8206e1 100644 --- a/avahi-common/strlst.c +++ b/avahi-common/strlst.c @@ -78,7 +78,7 @@ void avahi_string_list_free(AvahiStringList *l) { } } -static AvahiStringList* string_list_reverse(AvahiStringList *l) { +AvahiStringList* avahi_string_list_reverse(AvahiStringList *l) { AvahiStringList *r = NULL, *n; while (l) { @@ -96,7 +96,7 @@ gchar* avahi_string_list_to_string(AvahiStringList *l) { guint s = 0; gchar *t, *e; - l = string_list_reverse(l); + l = avahi_string_list_reverse(l); for (n = l; n; n = n->next) { if (n != l) @@ -120,7 +120,7 @@ gchar* avahi_string_list_to_string(AvahiStringList *l) { g_assert(e); } - l = string_list_reverse(l); + l = avahi_string_list_reverse(l); *e = 0; @@ -136,7 +136,7 @@ guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size) g_assert(data); - l = string_list_reverse(l); + l = avahi_string_list_reverse(l); c = data; for (n = l; n; n = n->next) { @@ -158,7 +158,7 @@ guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size) used += 1+ k; } - l = string_list_reverse(l); + l = avahi_string_list_reverse(l); } else { AvahiStringList *n; @@ -241,7 +241,7 @@ AvahiStringList *avahi_string_list_copy(const AvahiStringList *l) { for (; l; l = l->next) r = avahi_string_list_add_arbitrary(r, l->text, l->size); - return string_list_reverse(r); + return avahi_string_list_reverse(r); } AvahiStringList *avahi_string_list_new_from_array(const gchar *array[], gint length) { @@ -255,3 +255,12 @@ AvahiStringList *avahi_string_list_new_from_array(const gchar *array[], gint len return r; } + +guint avahi_string_list_length(const AvahiStringList *l) { + guint n = 0; + + for (; l; l = l->next) + n++; + + return n; +} diff --git a/avahi-common/strlst.h b/avahi-common/strlst.h index 85a16f4..99a9d2a 100644 --- a/avahi-common/strlst.h +++ b/avahi-common/strlst.h @@ -93,6 +93,12 @@ gboolean avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList /** Copy a string list */ AvahiStringList *avahi_string_list_copy(const AvahiStringList *l); +/** Reverse the string list. */ +AvahiStringList* avahi_string_list_reverse(AvahiStringList *l); + +/** Return the number of elements in the string list */ +guint avahi_string_list_length(const AvahiStringList *l); + AVAHI_C_DECL_END #endif diff --git a/avahi-daemon/DBUS-API b/avahi-daemon/DBUS-API index 4a8f561..5acee5f 100644 --- a/avahi-daemon/DBUS-API +++ b/avahi-daemon/DBUS-API @@ -7,7 +7,7 @@ org.freedesktop.Avahi.Server -- Accessible through /org/freedeskto string GetVersionString() [int32 interface, int32 protocol, string host_name, int32 aprotocol, string address] ResolveHostName(int32 interface, int32 protocol, string name, int32 aprotocol) [int32 interface, int32 protocol, int32 aprotocol, string address, string host_name] ResolveAddress(int32 interface, int32 protocol, string address) -TODO: [int32 interface, int32 protocol, string name, string type, string domain, string host, int32 aprotocol, string address, uint16 port, string txt[]] ResolveService(int32 interface, int32 protocol, string name, string type, string domain, int32 aprotocol) + [int32 interface, int32 protocol, string name, string type, string domain, string host, int32 aprotocol, string address, uint16 port, string txt[]] ResolveService(int32 interface, int32 protocol, string name, string type, string domain, int32 aprotocol) path EntryGroupNew() -- Creates a new org.freedesktop.Avahi.EntryGroup object path DomainBrowserNew(int32 interface, int32 protocol, string domain, int32 btype) path ServiceTypeBrowserNew(int32 interface, int32 protocol, string domain) diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c index ab30a91..ced746c 100644 --- a/avahi-daemon/dbus-protocol.c +++ b/avahi-daemon/dbus-protocol.c @@ -45,9 +45,6 @@ #define AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER AVAHI_DBUS_NAME".ServiceTypeBrowser" #define AVAHI_DBUS_INTERFACE_SERVICE_BROWSER AVAHI_DBUS_NAME".ServiceBrowser" -/* Needs wrapping: - - AvahiServiceResolver */ - typedef struct Server Server; typedef struct Client Client; typedef struct EntryGroupInfo EntryGroupInfo; @@ -803,6 +800,76 @@ static void service_browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interf dbus_message_unref(m); } +static void service_resolver_callback( + AvahiServiceResolver *r, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiResolverEvent event, + const gchar *name, + const gchar *type, + const gchar *domain, + const gchar *host_name, + const AvahiAddress *a, + guint16 port, + AvahiStringList *txt, + gpointer userdata) { + + ServiceResolverInfo *i = userdata; + DBusMessage *reply; + + g_assert(r); + g_assert(host_name); + g_assert(i); + + if (event == AVAHI_RESOLVER_FOUND) { + char t[256], *pt = t; + gint32 i_interface, i_protocol, i_aprotocol; + gchar **array; + guint n, j; + AvahiStringList *p; + + g_assert(a); + avahi_address_snprint(t, sizeof(t), a); + + i_interface = (gint32) interface; + i_protocol = (gint32) protocol; + i_aprotocol = (gint32) a->family; + + array = g_new(gchar*, (n = avahi_string_list_length(txt))); + + /** FIXME: DBUS doesn't support strings that include NUL bytes (?) */ + for (p = txt, j = n-1; p; p = p->next, j--) + array[j] = g_strndup((gchar*) p->text, p->size); + + reply = dbus_message_new_method_return(i->message); + dbus_message_append_args( + reply, + DBUS_TYPE_INT32, &i_interface, + DBUS_TYPE_INT32, &i_protocol, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &domain, + DBUS_TYPE_STRING, &host_name, + DBUS_TYPE_INT32, &i_aprotocol, + DBUS_TYPE_STRING, &pt, + DBUS_TYPE_UINT16, &port, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, n, + DBUS_TYPE_INVALID); + + for (j = 0; j < n; j++) + g_free(array[j]); + + } else { + g_assert(event == AVAHI_RESOLVER_TIMEOUT); + reply = dbus_message_new_error(i->message, "org.freedesktop.Avahi.TimeoutError", NULL); + } + + dbus_connection_send(server->bus, reply, NULL); + dbus_message_unref(reply); + + service_resolver_free(i); +} + static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) { DBusError error; @@ -1090,6 +1157,43 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void dbus_connection_register_object_path(c, i->path, &vtable, i); return respond_path(c, m, i->path); + + } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ResolveService")) { + Client *client; + gint32 interface, protocol, aprotocol; + gchar *name, *type, *domain; + ServiceResolverInfo *i; + + if (!dbus_message_get_args( + m, &error, + DBUS_TYPE_INT32, &interface, + DBUS_TYPE_INT32, &protocol, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &domain, + DBUS_TYPE_INT32, &aprotocol, + DBUS_TYPE_INVALID) || !name || !*name || !type || !*type) { + avahi_log_warn("Error parsing Server::ResolveService message"); + goto fail; + } + + client = client_get(dbus_message_get_sender(m), TRUE); + + if (!*domain) + domain = NULL; + + i = g_new(ServiceResolverInfo, 1); + i->client = client; + i->message = dbus_message_ref(m); + AVAHI_LLIST_PREPEND(ServiceResolverInfo, service_resolvers, client->service_resolvers, i); + + if (!(i->service_resolver = avahi_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) { + service_resolver_free(i); + avahi_log_warn("Failed to create service resolver"); + goto fail; + } + + return DBUS_HANDLER_RESULT_HANDLED; } avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); diff --git a/avahi-daemon/dbus-test.py b/avahi-daemon/dbus-test.py index 30bd261..3cbe19c 100755 --- a/avahi-daemon/dbus-test.py +++ b/avahi-daemon/dbus-test.py @@ -52,6 +52,9 @@ stb.connect_to_signal('ItemRemove', lambda interface, protocol, type, domain: se def service_browser_callback(a, interface, protocol, name, type, domain): print "SERVICE_BROWSER: %s %i %i %s %s %s" % (a, interface, protocol, name, type, domain) + if a == "NEW": + print server.ResolveService(interface, protocol, name, type, domain, 0) + sb = dbus.Interface(bus.get_object("org.freedesktop.Avahi", server.ServiceBrowserNew(0, 0, "_http._tcp", "")), 'org.freedesktop.Avahi.ServiceBrowser') sb.connect_to_signal('ItemNew', lambda interface, protocol, name, type, domain: service_browser_callback("NEW", interface, protocol, name, type, domain)) sb.connect_to_signal('ItemRemove', lambda interface, protocol, name, type, domain: service_browser_callback("REMOVE", interface, protocol, name, type, domain)) diff --git a/todo b/todo index 5d2346d..4d21a93 100644 --- a/todo +++ b/todo @@ -1,7 +1,7 @@ todo: * finish DBUS stuff: - - wrap missing objects - introspection + - allow NUL bytes in TXT records * release! later: -- cgit