From b91af54d2a2b83648a844d2036254dab26c6a33c Mon Sep 17 00:00:00 2001 From: Patrik Weiskircher Date: Sat, 2 Jun 2007 17:06:08 +0000 Subject: Added Bonjour zeroconf support. This works now natively on MacOS X. I couldn't test mDNSResponder support on Linux, as Debian doesn't include it - but should work as well. git-svn-id: https://svn.musicpd.org/mpd/trunk@6453 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- configure.ac | 34 ++++++++++------- src/zeroconf.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 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 + +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 } -- cgit v1.2.3