[libdmapsharing] Start attempt to make Apple dns_sd DMAPMdnsBrowser work with multiple shares (thanks Daniel Svensson
- From: W. Michael Petullo <wmpetullo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdmapsharing] Start attempt to make Apple dns_sd DMAPMdnsBrowser work with multiple shares (thanks Daniel Svensson
- Date: Thu, 7 Jul 2011 03:39:02 +0000 (UTC)
commit dfce195fe7fbf0dab9d075ac44596598ba2f5d03
Author: W. Michael Petullo <mike flyn org>
Date: Wed Jul 6 22:36:39 2011 -0500
Start attempt to make Apple dns_sd DMAPMdnsBrowser work with multiple shares (thanks Daniel Svensson)
Signed-off-by: W. Michael Petullo <mike flyn org>
libdmapsharing/dmap-mdns-browser-dnssd.c | 303 +++++++++++++++---------------
1 files changed, 149 insertions(+), 154 deletions(-)
---
diff --git a/libdmapsharing/dmap-mdns-browser-dnssd.c b/libdmapsharing/dmap-mdns-browser-dnssd.c
index ef9212e..3a130e5 100644
--- a/libdmapsharing/dmap-mdns-browser-dnssd.c
+++ b/libdmapsharing/dmap-mdns-browser-dnssd.c
@@ -27,13 +27,25 @@
#include <glib.h>
#include <glib-object.h>
-#include "config.h"
#include "dmap-mdns-browser.h"
struct _DMAPMdnsBrowserPrivate
{
DMAPMdnsBrowserServiceType service_type;
+ DNSServiceRef sd_browse_ref;
+
+ GSList *services;
+ GSList *resolvers;
+ GSList *backlog;
+};
+
+typedef struct _ServiceContext
+{
+ DNSServiceRef ref;
+
+ DMAPMdnsBrowser *browser;
+
DNSServiceFlags flags;
uint16_t port;
@@ -43,13 +55,7 @@ struct _DMAPMdnsBrowserPrivate
gchar *full_name;
gchar *host_target;
gchar *domain;
-
- DNSServiceRef sd_service_ref;
- DNSServiceRef sd_browse_ref;
-
- GSList *services;
- GSList *resolvers;
-};
+} ServiceContext;
enum
{
@@ -58,34 +64,43 @@ enum
LAST_SIGNAL
};
+static void
+service_context_free (ServiceContext *ctx)
+{
+ DNSServiceRefDeallocate (ctx->ref);
+ g_object_unref (ctx->browser);
+ g_free (ctx->service_name);
+ g_free (ctx->full_name);
+ g_free (ctx->host_target);
+ g_free (ctx->domain);
+}
+
static gboolean
-add_sd_to_event_loop (DMAPMdnsBrowser * browser, DNSServiceRef sdRef);
+add_browse_to_event_loop (DMAPMdnsBrowser * browser);
-static void
+static gboolean
+add_resolve_to_event_loop (ServiceContext * browser, DNSServiceRef ref);
+
+static void
dmap_mdns_browser_class_init (DMAPMdnsBrowserClass * klass);
-static void
+static void
dmap_mdns_browser_init (DMAPMdnsBrowser * browser);
-static void
+static void
dmap_mdns_browser_dispose (GObject * object);
-static void
+static void
dmap_mdns_browser_finalize (GObject * object);
-static void
+static void
dnssd_browser_init (DMAPMdnsBrowser * browser);
-static void
-free_service (DMAPMdnsBrowserService * service);
-
static void
-browser_add_service (DMAPMdnsBrowser * browser,
- const gchar * service_name, const gchar * domain);
+free_service (DMAPMdnsBrowserService * service);
static gboolean
-dmap_mdns_browser_resolve (DMAPMdnsBrowser * browser,
- const gchar * name, const gchar * domain);
+dmap_mdns_browser_resolve (ServiceContext *context);
static void
dns_service_browse_reply (DNSServiceRef sdRef,
@@ -115,7 +130,7 @@ static guint dmap_mdns_browser_signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (DMAPMdnsBrowser, dmap_mdns_browser, G_TYPE_OBJECT);
-static void
+static void
dmap_mdns_browser_init (DMAPMdnsBrowser * browser)
{
g_debug ("dmap_mdns_browser_init ()");
@@ -128,83 +143,103 @@ static gboolean
browse_result_available_cb (GIOChannel * gio,
GIOCondition condition, DMAPMdnsBrowser * browser)
{
- if (condition & G_IO_HUP) {
- g_error ("DNS-SD browser socket closed");
+ if (condition & (G_IO_HUP | G_IO_ERR )) {
+ g_warning ("DNS-SD browser socket closed");
+ return FALSE;
}
DNSServiceErrorType err =
DNSServiceProcessResult (browser->priv->sd_browse_ref);
- if (!kDNSServiceErr_NoError == err) {
- g_error ("Error processing DNS-SD browse result");
- } else {
- err = DNSServiceResolve (&(browser->priv->sd_service_ref),
- browser->priv->flags,
- browser->priv->interface_index,
- browser->priv->service_name,
- service_type_name[browser->priv->service_type],
- browser->priv->domain,
- (DNSServiceResolveReply)
- dns_service_resolve_reply,
- (void *) browser);
+ if (err != kDNSServiceErr_NoError) {
+ g_warning ("Error processing DNS-SD browse result");
+ return FALSE;
}
- if (kDNSServiceErr_NoError == err) {
+ for (; browser->priv->backlog; browser->priv->backlog = g_slist_remove_link (browser->priv->backlog, browser->priv->backlog)) {
+ ServiceContext *ctx = (ServiceContext *) browser->priv->backlog->data;
+ DNSServiceRef ref;
+
+ err = DNSServiceResolve (&ref,
+ ctx->flags,
+ ctx->interface_index,
+ ctx->service_name,
+ service_type_name[browser->priv->service_type],
+ ctx->domain,
+ (DNSServiceResolveReply)
+ dns_service_resolve_reply,
+ (void *) ctx);
+
+ if (err != kDNSServiceErr_NoError) {
+ g_warning ("Error setting up DNS-SD resolve handler");
+ service_context_free (ctx);
+ continue;
+ }
+
+ ctx->ref = ref;
+
g_debug ("Success processing DNS-SD browse result");
- add_sd_to_event_loop (browser, browser->priv->sd_service_ref);
- } else {
- g_error ("Error setting up DNS-SD resolve handler");
+ add_resolve_to_event_loop (ctx, ref);
}
return TRUE;
}
static gboolean
-service_result_available_cb (GIOChannel * gio,
- GIOCondition condition,
- DMAPMdnsBrowser * browser)
+service_result_available_cb (GIOChannel * gio, GIOCondition condition,
+ ServiceContext *context)
{
- if (condition & G_IO_HUP) {
- g_error ("DNS-SD service socket closed");
+ if (condition & (G_IO_HUP | G_IO_ERR)) {
+ g_warning ("DNS-SD service socket closed");
+ service_context_free (context);
+ return FALSE;
}
- DNSServiceErrorType err =
- DNSServiceProcessResult (browser->priv->sd_service_ref);
-
- if (!kDNSServiceErr_NoError == err) {
- g_error ("Error processing DNS-SD service result");
- } else {
- browser_add_service (browser,
- (gchar *) browser->priv->service_name,
- (gchar *) browser->priv->domain);
+ DNSServiceErrorType err = DNSServiceProcessResult (context->ref);
+
+ if (err != kDNSServiceErr_NoError) {
+ g_warning ("Error processing DNS-SD service result");
+ return FALSE;
}
- return TRUE;
+ dmap_mdns_browser_resolve (context);
+
+ return FALSE;
}
static gboolean
-add_sd_to_event_loop (DMAPMdnsBrowser * browser, DNSServiceRef sd_ref)
+add_browse_to_event_loop (DMAPMdnsBrowser *browser)
{
- int dns_sd_fd = DNSServiceRefSockFD (sd_ref);
+ int dns_sd_fd = DNSServiceRefSockFD (browser->priv->sd_browse_ref);
GIOChannel *dns_sd_chan = g_io_channel_unix_new (dns_sd_fd);
- GIOFunc result_func = NULL;
- if (browser->priv->sd_browse_ref == sd_ref) {
- result_func = (GIOFunc) browse_result_available_cb;
- } else if (browser->priv->sd_service_ref) {
- result_func = (GIOFunc) service_result_available_cb;
+ if (!g_io_add_watch (dns_sd_chan,
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
+ (GIOFunc) browse_result_available_cb, browser)) {
+ g_error ("Error adding SD to event loop");
}
+ return TRUE;
+}
+
+static gboolean
+add_resolve_to_event_loop (ServiceContext *context, DNSServiceRef sd_ref)
+{
+ int dns_sd_fd = DNSServiceRefSockFD (sd_ref);
+
+ GIOChannel *dns_sd_chan = g_io_channel_unix_new (dns_sd_fd);
+
if (!g_io_add_watch (dns_sd_chan,
- G_IO_IN | G_IO_HUP | G_IO_ERR,
- result_func, browser)) {
- g_error ("Error adding SD to event loop");
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
+ (GIOFunc) service_result_available_cb, context)) {
+ g_warning ("Error adding SD to event loop");
}
return TRUE;
}
+
static void
dns_service_browse_reply (DNSServiceRef sd_ref,
DNSServiceFlags flags,
@@ -212,35 +247,30 @@ dns_service_browse_reply (DNSServiceRef sd_ref,
DNSServiceErrorType error_code,
const char *service_name,
const char *regtype,
- const char *reply_domain, void *context)
+ const char *reply_domain, void *udata)
{
- if (error_code == kDNSServiceErr_NoError) {
- g_debug ("dns_service_browse_reply (): success");
-
- if (flags & kDNSServiceFlagsAdd) {
- g_debug ("adding a service");
-
- // Cast the context pointer to a DMAPMdnsBrowser
- DMAPMdnsBrowser *browser = (DMAPMdnsBrowser *) context;
-
- browser->priv->flags = flags;
- browser->priv->interface_index = interface_index;
-
- g_free (browser->priv->service_name);
- browser->priv->service_name = g_strdup (service_name);
-
- /* NOTE: regtype is ignored as it is assumed to be
- * the same as what we were browsing for in the
- * first place.
- */
- g_free (browser->priv->domain);
- browser->priv->domain = g_strdup (reply_domain);
- } else if (flags & kDNSServiceFlagsMoreComing) {
- g_debug ("more incoming information");
- }
- } else {
+ if (error_code != kDNSServiceErr_NoError) {
g_debug ("dnsServiceBrowserReply (): fail");
+ return;
}
+
+ if (!(flags & kDNSServiceFlagsAdd)) {
+ return;
+ }
+
+ g_debug ("adding a service: %s", service_name);
+
+ // Cast the context pointer to a DMAPMdnsBrowser
+ DMAPMdnsBrowser *browser = (DMAPMdnsBrowser *) udata;
+
+ ServiceContext *context = g_new0 (ServiceContext, 1);
+ context->browser = g_object_ref (browser);
+ context->flags = flags;
+ context->interface_index = interface_index;
+ context->service_name = g_strdup (service_name);
+ context->domain = g_strdup (reply_domain);
+
+ browser->priv->backlog = g_slist_prepend (browser->priv->backlog, context);
}
static void
@@ -252,48 +282,28 @@ dns_service_resolve_reply (DNSServiceRef sd_ref,
const char *hosttarget,
uint16_t port,
uint16_t txt_len,
- const char *txt_record, void *context)
+ const char *txt_record, void *udata)
{
- // Cast the context pointer to a DMAPMdnsBrowser
- DMAPMdnsBrowser *browser = (DMAPMdnsBrowser *) context;
-
- if (kDNSServiceErr_NoError == error_code) {
- g_debug ("dns_service_resolve_reply (): success");
-
- browser->priv->flags = flags;
- browser->priv->interface_index = interface_index;
- browser->priv->port = htons (port);
-
- g_free (browser->priv->full_name);
- browser->priv->full_name = g_strdup (fullname);
+ ServiceContext *ctx = (ServiceContext *) udata;
- g_free (browser->priv->host_target);
- browser->priv->host_target = g_strdup (hosttarget);
- } else {
+ if (error_code != kDNSServiceErr_NoError) {
g_debug ("dns_service_resolve_reply (): fail");
+ return;
}
+
+ g_debug ("dns_service_resolve_reply (): success");
+
+ ctx->flags = flags;
+ ctx->interface_index = interface_index;
+ ctx->port = htons (port);
+ ctx->full_name = g_strdup (fullname);
+ ctx->host_target = g_strdup (hosttarget);
}
static void
dnssd_browser_init (DMAPMdnsBrowser * browser)
{
g_debug ("dnssd_browser_init()");
-
- browser->priv->flags = kDNSServiceFlagsDefault;
- browser->priv->port = 0;
- browser->priv->interface_index = 0;
-
- g_free (browser->priv->domain);
- browser->priv->domain = g_strdup ("");
-
- g_free (browser->priv->service_name);
- browser->priv->service_name = g_strdup ("");
-
- g_free (browser->priv->full_name);
- browser->priv->full_name = g_strdup ("");
-
- g_free (browser->priv->host_target);
- browser->priv->host_target = g_strdup ("");
}
static void
@@ -351,8 +361,7 @@ dmap_mdns_browser_new (DMAPMdnsBrowserServiceType type)
}
static gboolean
-dmap_mdns_browser_resolve (DMAPMdnsBrowser * browser,
- const gchar * name, const gchar * domain)
+dmap_mdns_browser_resolve (ServiceContext *context)
{
g_debug ("dmap_mdns_browser_resolve ()");
@@ -363,33 +372,24 @@ dmap_mdns_browser_resolve (DMAPMdnsBrowser * browser,
// FIXME: The name and service_name variables need to be renamed.
// Wait until working on DACP because I think this is when
// they are different. See Avahi code.
- service->service_name = g_strdup (name);
- service->name = g_strdup (name);
- service->host = g_strdup (browser->priv->host_target);
- service->port = browser->priv->port;
+ service->service_name = g_strdup (context->service_name);
+ service->name = g_strdup (context->service_name);
+ service->host = g_strdup (context->host_target);
+ service->port = context->port;
service->pair = NULL;
service->password_protected = FALSE;
// add to the services list
- browser->priv->services =
- g_slist_append (browser->priv->services, service);
+ context->browser->priv->services =
+ g_slist_append (context->browser->priv->services, service);
- // notify all listeners
- g_signal_emit (browser,
+ // notify all listeners
+ g_signal_emit (context->browser,
dmap_mdns_browser_signals[SERVICE_ADDED], 0, service);
return TRUE;
}
-static void
-browser_add_service (DMAPMdnsBrowser * browser,
- const gchar * service_name, const gchar * domain)
-{
- g_debug ("browser_add_service ()");
-
- dmap_mdns_browser_resolve (browser, service_name, domain);
-}
-
gboolean
dmap_mdns_browser_start (DMAPMdnsBrowser * browser, GError ** error)
{
@@ -399,34 +399,29 @@ dmap_mdns_browser_start (DMAPMdnsBrowser * browser, GError ** error)
DNSServiceErrorType browse_err = kDNSServiceErr_Unknown;
- browse_err = DNSServiceBrowse (&(browser->priv->sd_browse_ref),
- browser->priv->flags,
- browser->priv->interface_index,
- service_type_name[browser->priv->service_type],
- browser->priv->domain,
- (DNSServiceBrowseReply)
- dns_service_browse_reply,
- (void *) browser);
+ browse_err = DNSServiceBrowse (&(browser->priv->sd_browse_ref), 0,
+ kDNSServiceInterfaceIndexAny,
+ service_type_name[browser->priv->service_type], 0,
+ (DNSServiceBrowseReply) dns_service_browse_reply,
+ (void *) browser);
if (kDNSServiceErr_NoError == browse_err) {
g_debug ("*** Browse Success ****");
- add_sd_to_event_loop (browser, browser->priv->sd_browse_ref);
+ add_browse_to_event_loop (browser);
}
return is_success;
}
/**
- * Note that you must terminate the connection with the daemon and
+ * Note that you must terminate the connection with the daemon and
* free any memory associated with DNSServiceRef
*/
gboolean
dmap_mdns_browser_stop (DMAPMdnsBrowser * browser, GError ** error)
{
DNSServiceRefDeallocate (browser->priv->sd_browse_ref);
- DNSServiceRefDeallocate (browser->priv->sd_service_ref);
-
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]