aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac34
-rw-r--r--src/zeroconf.c116
2 files changed, 127 insertions, 23 deletions
diff --git a/configure.ac b/configure.ac
index 46398fb96..02cb6b9ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -586,24 +586,32 @@ no|avahi|bonjour)
esac
if test x$with_zeroconf != xno; then
- if test x$with_zeroconf = xauto; then
+ if test x$with_zeroconf = xavahi -o x$with_zeroconf = xauto; then
PKG_CHECK_MODULES([AVAHI], [avahi-client],
- [with_zeroconf=avahi;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])] MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS",
- [with_zeroconf=auto])
- elif test x$with_zeroconf = xavahi; then
- PKG_CHECK_MODULES([AVAHI], [avahi-client],
- [with_zeroconf=avahi;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])] MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS")
+ [found_avahi=1;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])] MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS", found_avahi=0)
fi
- # In the future, should add bonjour support (for OSX) and check at autodetect
- # time
- #if test x$with_zeroconf = xbonjour -o x$with_zeroconf = xauto; then
- if test x$with_zeroconf = xbonjour; then
- AC_MSG_WARN([Bonjour support has not been implemented yet, disabling Zeroconf])
- with_zeroconf=no
+ if test x$found_avahi = x1; then
+ with_zeroconf=avahi
+ else
+ if test x$with_zeroconf = xavahi; then
+ with_zeroconf=no
+ fi
+ fi
+
+ if test x$with_zeroconf = xbonjour -o x$with_zeroconf = xauto; then
+ AC_CHECK_HEADER(dns_sd.h, [found_bonjour=1;AC_DEFINE(HAVE_BONJOUR,1,[Define to enable Bonjour Zeroconf support])],[found_bonjour=0])
+ fi
+
+ if test x$found_bonjour = x1; then
+ with_zeroconf=bonjour
+ else
+ if test x$with_zeroconf = xbonjour; then
+ with_zeroconf=no
+ fi
fi
- if test x$with_zeroconf = xauto; then
+ if test x$with_zeroconf = xauto -o x$with_zeroconf = xno; then
AC_MSG_WARN([No supported Zeroconf backend found, disabling Zeroconf])
with_zeroconf=no
fi
diff --git a/src/zeroconf.c b/src/zeroconf.c
index 6c2c8e717..e7ea05d74 100644
--- a/src/zeroconf.c
+++ b/src/zeroconf.c
@@ -35,6 +35,15 @@
*/
#define SERVICE_NAME "Music Player"
+static struct ioOps zeroConfIo = {
+};
+
+#ifdef HAVE_BONJOUR
+#include <dns_sd.h>
+
+static DNSServiceRef dnsReference;
+#endif
+
/* Here is the implementation for Avahi (http://avahi.org) Zeroconf support */
#ifdef HAVE_AVAHI
@@ -55,10 +64,6 @@ static int avahiRunning;
static int avahiFdset( fd_set* rfds, fd_set* wfds, fd_set* efds );
static int avahiFdconsume( int fdCount, fd_set* rfds, fd_set* wfds, fd_set* efds );
-static struct ioOps avahiIo = {
- .fdset = avahiFdset,
- .consume = avahiFdconsume,
-};
/* Forward Declaration */
static void avahiRegisterService(AvahiClient *c);
@@ -451,19 +456,94 @@ static void init_avahi(const char *serviceName)
goto fail;
}
- avahiIo.fdset = avahiFdset;
- avahiIo.consume = avahiFdconsume;
- registerIO( &avahiIo );
+ zeroConfIo.fdset = avahiFdset;
+ zeroConfIo.consume = avahiFdconsume;
+ registerIO( &zeroConfIo );
return;
fail:
finishZeroconf();
}
-#else /* !HAVE_AVAHI */
-static void init_avahi(const char *serviceName) { }
#endif /* HAVE_AVAHI */
+#ifdef HAVE_BONJOUR
+static int dnsRegisterFdset(fd_set* rfds, fd_set* wfds, fd_set* efds)
+{
+ int fd;
+
+ if (dnsReference == NULL)
+ return -1;
+
+ fd = DNSServiceRefSockFD(dnsReference);
+ if (fd == -1)
+ return -1;
+
+ FD_SET(fd, rfds);
+
+ return fd;
+}
+
+static int dnsRegisterFdconsume(int fdCount, fd_set* rfds, fd_set* wfds,
+ fd_set* efds)
+{
+ int fd;
+
+ if (dnsReference == NULL)
+ return -1;
+
+ fd = DNSServiceRefSockFD(dnsReference);
+ if (fd == -1)
+ return -1;
+
+ if (FD_ISSET(fd, rfds)) {
+ FD_CLR(fd, rfds);
+
+ DNSServiceProcessResult(dnsReference);
+
+ return fdCount - 1;
+ }
+
+ return fdCount;
+}
+
+static void dnsRegisterCallback (DNSServiceRef sdRef, DNSServiceFlags flags,
+ DNSServiceErrorType errorCode, const char *name,
+ const char *regtype, const char *domain, void *context)
+{
+ if (errorCode != kDNSServiceErr_NoError) {
+ ERROR("Failed to register zeroconf service.\n");
+
+ DNSServiceRefDeallocate(dnsReference);
+ dnsReference = NULL;
+ deregisterIO( &zeroConfIo );
+ } else {
+ DEBUG("Registered zeroconf service with name '%s'\n", name);
+ }
+}
+
+static void init_zeroconf_osx(const char *serviceName)
+{
+ DNSServiceErrorType error = DNSServiceRegister(&dnsReference,
+ 0, 0, serviceName, SERVICE_TYPE, NULL, NULL, htons(boundPort), 0,
+ NULL, dnsRegisterCallback, NULL);
+
+ if (error != kDNSServiceErr_NoError) {
+ ERROR("Failed to register zeroconf service.\n");
+
+ if (dnsReference) {
+ DNSServiceRefDeallocate(dnsReference);
+ dnsReference = NULL;
+ }
+ return;
+ }
+
+ zeroConfIo.fdset = dnsRegisterFdset;
+ zeroConfIo.consume = dnsRegisterFdconsume;
+ registerIO( &zeroConfIo );
+}
+#endif
+
void initZeroconf(void)
{
const char* serviceName = SERVICE_NAME;
@@ -473,14 +553,21 @@ void initZeroconf(void)
if (param && strlen(param->value) > 0)
serviceName = param->value;
+
+#ifdef HAVE_AVAHI
init_avahi(serviceName);
+#endif
+
+#ifdef HAVE_BONJOUR
+ init_zeroconf_osx(serviceName);
+#endif
}
void finishZeroconf(void)
{
#ifdef HAVE_AVAHI
DEBUG( "Avahi: Shutting down interface\n" );
- deregisterIO( &avahiIo );
+ deregisterIO( &zeroConfIo );
if( avahiGroup ) {
avahi_entry_group_free( avahiGroup );
@@ -495,4 +582,13 @@ void finishZeroconf(void)
avahi_free( avahiName );
avahiName = NULL;
#endif /* HAVE_AVAHI */
+
+#ifdef HAVE_BONJOUR
+ deregisterIO( &zeroConfIo );
+ if (dnsReference != NULL) {
+ DNSServiceRefDeallocate(dnsReference);
+ dnsReference = NULL;
+ DEBUG("Deregistered Zeroconf service.\n");
+ }
+#endif
}