]> git.meshlink.io Git - catta/commitdiff
DBUS: Wrap service resolver
authorLennart Poettering <lennart@poettering.net>
Fri, 29 Jul 2005 01:42:21 +0000 (01:42 +0000)
committerLennart Poettering <lennart@poettering.net>
Fri, 29 Jul 2005 01:42:21 +0000 (01:42 +0000)
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
avahi-common/strlst.h
avahi-daemon/DBUS-API
avahi-daemon/dbus-protocol.c
avahi-daemon/dbus-test.py
todo

index d962188d080c73a4657af9bc85cf1b3ea380bef4..d8206e1c8c391073b179360789318291c34aec07 100644 (file)
@@ -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;
+}
index 85a16f410e4458275eaba1f200c0043a6d8635d8..99a9d2aa2b0fb0769fa11ab9dfcf8d22fa89f04f 100644 (file)
@@ -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
index 4a8f561d90da33019ea72d81371768348ebe1ee8..5acee5f87b152d522ba9a6d43d6adc5120fc8b5b 100644 (file)
@@ -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)
index ab30a91cdbc657c9241d1a56c4d587d8651da8ec..ced746c220efb000eb64aab97be4d480009b9150 100644 (file)
@@ -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));
index 30bd261333d4734204aa84b007cc9671a1bfca3c..3cbe19c6aae846a53e45bd6b8bfa8ee62e90e820 100755 (executable)
@@ -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 5d2346dd0319b6a19d3cc77f78fa884b0a8af646..4d21a939919b90634ae8bd37f43ff66a51246209 100644 (file)
--- a/todo
+++ b/todo
@@ -1,7 +1,7 @@
 todo:
 * finish DBUS stuff:
-       - wrap missing objects
        - introspection
+    - allow NUL bytes in TXT records
 * release!
 
 later: