* Add DomainBrowser support to C client API
authorTrent Lloyd <lathiat@bur.st>
Thu, 11 Aug 2005 14:04:13 +0000 (14:04 +0000)
committerTrent Lloyd <lathiat@bur.st>
Thu, 11 Aug 2005 14:04:13 +0000 (14:04 +0000)
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@289 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-client/Makefile.am
avahi-client/browser.c [new file with mode: 0644]
avahi-client/client-test.c
avahi-client/client.c
avahi-client/client.h
avahi-client/entrygroup.c
avahi-client/internal.h

index d42f33d..2c80e84 100644 (file)
@@ -44,7 +44,8 @@ lib_LTLIBRARIES = \
 
 libavahi_client_la_SOURCES = \
        client.c client.h \
-       entrygroup.c
+       entrygroup.c \
+       browser.c
 
 client_test_SOURCES = \
        client-test.c
diff --git a/avahi-client/browser.c b/avahi-client/browser.c
new file mode 100644 (file)
index 0000000..292162c
--- /dev/null
@@ -0,0 +1,139 @@
+/* $Id$ */
+
+/***
+  This file is part of avahi.
+  avahi 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.
+  avahi 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 Lesser General
+  Public License for more details.
+  You should have received a copy of the GNU Lesser General Public
+  License along with avahi; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <avahi-client/client.h>
+#include <avahi-common/dbus.h>
+#include <avahi-common/llist.h>
+#include <avahi-common/error.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <stdlib.h>
+
+#include "client.h"
+#include "internal.h"
+
+AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, char *domain, AvahiDomainBrowserType btype, AvahiDomainBrowserCallback callback, void *user_data)
+{
+    AvahiDomainBrowser *tmp = NULL;
+    DBusMessage *message = NULL, *reply;
+    DBusError error;
+    char *path;
+
+    if (client == NULL)
+        return NULL;
+
+    dbus_error_init (&error);
+
+    message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER,
+            AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew");
+
+    if (!dbus_message_append_args (message, DBUS_TYPE_INT32, &interface, DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INT32, &btype, DBUS_TYPE_INVALID))
+        goto dbus_error;
+
+    reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error);
+
+    if (dbus_error_is_set (&error) || reply == NULL)
+        goto dbus_error;
+
+    if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
+        goto dbus_error;
+
+    if (dbus_error_is_set (&error) || path == NULL)
+        goto dbus_error;
+
+    tmp = malloc (sizeof (AvahiDomainBrowser));
+    tmp->client = client;
+    tmp->callback = callback;
+    tmp->user_data = user_data;
+    tmp->path = strdup (path);
+
+    AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, tmp);
+
+    return tmp;
+
+dbus_error:
+    dbus_error_free (&error);
+    avahi_client_set_errno (client, AVAHI_ERR_DBUS_ERROR);
+
+    return NULL;
+}
+
+char*
+avahi_domain_browser_path (AvahiDomainBrowser *b)
+{
+    return b->path;
+}
+
+DBusHandlerResult
+avahi_entry_group_event (AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message)
+{
+    AvahiDomainBrowser *n, *db = NULL;
+    DBusError error;
+    const char *path;
+    char *domain;
+    int interface, protocol;
+
+    dbus_error_init (&error);
+
+    path = dbus_message_get_path (message);
+
+    printf ("bailing out 1\n");
+    if (path == NULL)
+        goto out;
+
+    for (n = client->domain_browsers; n != NULL; n = n->domain_browsers_next)
+    {
+        printf ("cmp: %s, %s\n", n->path, path);
+        if (strcmp (n->path, path) == 0) {
+            db = n;
+            break;
+        }
+    }
+
+    printf ("bailing out 2\n");
+    if (db == NULL)
+        goto out;
+
+    dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &interface,
+            DBUS_TYPE_INT32, &protocol, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INVALID);
+
+    printf ("bailing out 3\n");
+    if (dbus_error_is_set (&error))
+        goto out;
+
+    db->callback (db, interface, protocol, event, domain, db->user_data);
+
+    return DBUS_HANDLER_RESULT_HANDLED;
+
+out:
+    dbus_error_free (&error);
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
index 64ad9a5..f55d1e4 100644 (file)
@@ -31,9 +31,15 @@ avahi_client_callback (AvahiClient *c, AvahiClientState state, void *user_data)
 }
 
 void
-avahi_entry_group_callback (AvahiClient *c, AvahiEntryGroup *g, AvahiEntryGroupState state, void *user_data)
+avahi_entry_group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, void *user_data)
 {
-    printf ("Callback on %s, state -> %d, data -> %s\n", avahi_entry_group_get_path (g), state, (char*)user_data);
+    printf ("XXX: Callback on %s, state -> %d, data -> %s\n", avahi_entry_group_path (g), state, (char*)user_data);
+}
+
+void
+avahi_domain_browser_callback (AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, char *domain, void *user_data)
+{
+    printf ("XXX: Callback on %s, event -> %d, domain -> %s, data -> %s\n", avahi_domain_browser_path (b), event, domain, (char*)user_data);
 }
 
 int
@@ -43,6 +49,7 @@ main (int argc, char *argv[])
     AvahiClient *avahi;
     AvahiEntryGroup *group;
     AvahiStringList *txt;
+    AvahiDomainBrowser *domain;
     char *ret;
 
     loop = g_main_loop_new (NULL, FALSE);
@@ -74,7 +81,7 @@ main (int argc, char *argv[])
     if (group == NULL)
         printf ("Failed to create entry group object\n");
     else
-        printf ("Sucessfully created entry group, path %s\n", avahi_entry_group_get_path (group));
+        printf ("Sucessfully created entry group, path %s\n", avahi_entry_group_path (group));
 
     txt = avahi_string_list_new ("foo=bar", NULL);
 
@@ -82,6 +89,12 @@ main (int argc, char *argv[])
 
     avahi_entry_group_commit (group);
 
+    domain = avahi_domain_browser_new (avahi, AVAHI_IF_UNSPEC, AF_UNSPEC, "", AVAHI_DOMAIN_BROWSER_BROWSE, avahi_domain_browser_callback, "omghai3u");
+    if (domain == NULL)
+        printf ("Failed to create domain browser object\n");
+    else
+        printf ("Sucessfully created browser, path %s\n", avahi_domain_browser_path (domain));
+
     g_main_loop_run (loop);
 
     g_free (avahi);
index 43b9fc1..485444c 100644 (file)
@@ -158,28 +158,27 @@ filter_func (DBusConnection *bus, DBusMessage *message, void *data)
                 break;
             }
         }
-
+        
         if (group == NULL)
         {
             fprintf (stderr, "Received state change for unknown EntryGroup object (%s)\n", path);
         } else {
             int state;
             DBusError error;
-
             dbus_error_init (&error);
-
             dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID);
-
             if (dbus_error_is_set (&error))
             {
                 fprintf (stderr, "internal error parsing entrygroup statechange for %s\n", group->path);
                 goto out;
             }
-
             printf ("statechange (%s) to %d\n", group->path, state);
-            
             avahi_entry_group_state_change (group, state);
         }
+    } else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "ItemNew")) {
+        return avahi_entry_group_event (client, AVAHI_BROWSER_NEW, message);
+    } else if (dbus_message_is_signal (message, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "ItemRemove")) {
+        return avahi_entry_group_event (client, AVAHI_BROWSER_REMOVE, message);
     }
 
     return DBUS_HANDLER_RESULT_HANDLED;
@@ -200,6 +199,7 @@ avahi_client_new (AvahiClientCallback callback, void *user_data)
         goto fail;
 
     AVAHI_LLIST_HEAD_INIT(AvahiEntryGroup, tmp->groups);
+    AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, tmp->domain_browsers);
 
     dbus_error_init (&error);
 
index c368bb3..4e06762 100644 (file)
@@ -37,15 +37,22 @@ typedef struct _AvahiClient AvahiClient;
 
 typedef struct _AvahiEntryGroup AvahiEntryGroup;
 
+typedef struct _AvahiDomainBrowser AvahiDomainBrowser;
+
 /** States of a client object, note that AvahiServerStates are also emitted */
 typedef enum {
     AVAHI_CLIENT_DISCONNECTED = 100, /**< Lost DBUS connection to the Avahi daemon */
     AVAHI_CLIENT_RECONNECTED  = 101  /**< Regained connection to the daemon, all records need to be re-added */
 } AvahiClientState;
 
+/** The function prototype for the callback of an AvahiClient */
 typedef void (*AvahiClientCallback) (AvahiClient *s, AvahiClientState state, void* userdata);
 
-typedef void (*AvahiEntryGroupCallback) (AvahiClient *s, AvahiEntryGroup *g, AvahiEntryGroupState state, void* userdata);
+/** The function prototype for the callback of an AvahiEntryGroup */
+typedef void (*AvahiEntryGroupCallback) (AvahiEntryGroup *g, AvahiEntryGroupState state, void* userdata);
+
+/** The function prototype for the callback of an AvahiDomainBrowser */
+typedef void (*AvahiDomainBrowserCallback) (AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, char *domain, void *user_data);
 
 /** Creates a new client instance */
 AvahiClient* avahi_client_new (AvahiClientCallback callback, void *user_data);
@@ -96,7 +103,19 @@ avahi_entry_group_add_service (AvahiEntryGroup *group,
                                AvahiStringList *txt);
 
 /** Get the D-Bus path of an AvahiEntryGroup object, for debugging purposes only. */
-char* avahi_entry_group_get_path (AvahiEntryGroup *);
+char* avahi_entry_group_path (AvahiEntryGroup *);
+
+/** Get the D-Bus path of an AvahiDomainBrowser object, for debugging purposes only. */
+char* avahi_domain_browser_path (AvahiDomainBrowser *);
+
+/** Browse for domains on the local network */
+AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client,
+                                              AvahiIfIndex interface,
+                                              AvahiProtocol protocol,
+                                              char *domain,
+                                              AvahiDomainBrowserType btype,
+                                              AvahiDomainBrowserCallback callback,
+                                              void *user_data);
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 AVAHI_C_DECL_END
index 9760cd9..6c0613f 100644 (file)
@@ -45,7 +45,7 @@ void avahi_entry_group_state_change (AvahiEntryGroup *group, int state)
     if (group == NULL || group->callback == NULL)
         return;
 
-    group->callback (group->client, group, state, group->user_data);
+    group->callback (group, state, group->user_data);
 }
 
 AvahiEntryGroup*
@@ -249,7 +249,7 @@ avahi_entry_group_add_service (AvahiEntryGroup *group,
 }
 
 /* XXX: debug function */
-char* avahi_entry_group_get_path (AvahiEntryGroup *group)
+char* avahi_entry_group_path (AvahiEntryGroup *group)
 {
     if (group != NULL) return group->path;
     else return NULL;
index 6fea0b0..72c01de 100644 (file)
@@ -33,6 +33,7 @@ struct _AvahiClient
     AvahiClientCallback callback;
     void *user_data;
     AVAHI_LLIST_HEAD(AvahiEntryGroup, groups);
+    AVAHI_LLIST_HEAD(AvahiDomainBrowser, domain_browsers);
 };
 
 struct _AvahiEntryGroup {
@@ -43,6 +44,14 @@ struct _AvahiEntryGroup {
     AVAHI_LLIST_FIELDS(AvahiEntryGroup, groups);
 };
 
+struct _AvahiDomainBrowser {
+    char *path;
+    AvahiClient *client;
+    AvahiDomainBrowserCallback callback;
+    void *user_data;
+    AVAHI_LLIST_FIELDS(AvahiDomainBrowser, domain_browsers);
+};
+
 int avahi_client_set_errno (AvahiClient *client, int errno);
 
 void avahi_entry_group_state_change (AvahiEntryGroup *group, int state);