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 --- src/zeroconf.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 10 deletions(-) (limited to 'src/zeroconf.c') 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