diff --git a/Makefile b/Makefile index 5b58deda..1c640edb 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,10 @@ ifdef CONFIG_AVAHI SRCS += mdns_avahi.c endif +ifdef CONFIG_HAVE_DNS_SD_H +SRCS += mdns_dns_sd.c +endif + ifndef CONFIG_HAVE_GETOPT_H SRCS += getopt_long.c endif diff --git a/Makefile.tests b/Makefile.tests index f79157ea..357ed9cf 100644 --- a/Makefile.tests +++ b/Makefile.tests @@ -2,3 +2,9 @@ test_getopt: echo '#include ' > .test_getopt.c $(CC) $(CFLAGS) -c .test_getopt.c rm .test_getopt.c .test_getopt.o + +test_dns_sd: + echo '#include ' > .test_dns_sd.c + $(CC) $(CFLAGS) -c .test_dns_sd.c + rm .test_dns_sd.c .test_dns_sd.o + diff --git a/configure b/configure index a28a5954..ec1937c8 100755 --- a/configure +++ b/configure @@ -8,7 +8,7 @@ echo "// automatically generated file" > config.h LDFLAGS="${LDFLAGS} -lm -lpthread" -if make -f Makefile.tests test_getopt > /dev/null; then +if make -f Makefile.tests test_getopt > /dev/null 2>&1; then echo "getopt.h found" echo "#define CONFIG_HAVE_GETOPT_H" >> config.h echo "CONFIG_HAVE_GETOPT_H=yes" >> config.mk @@ -16,6 +16,14 @@ else echo "getopt.h not found (or compiler broken), using our own getopt_long." fi +if make -f Makefile.tests test_dns_sd > /dev/null 2>&1; then + echo "dns_sd.h found" + echo "#define CONFIG_HAVE_DNS_SD_H" >> config.h + echo "CONFIG_HAVE_DNS_SD_H=yes" >> config.mk +else + echo "dns_sd.h not found" +fi + # check for and use pkg-config package $2 with CONFIG_ var $3 do_pkg_config() { diff --git a/mdns.c b/mdns.c index f64557a3..7fc7bd62 100644 --- a/mdns.c +++ b/mdns.c @@ -39,9 +39,16 @@ extern mdns_backend mdns_external_avahi; extern mdns_backend mdns_external_dns_sd; extern mdns_backend mdns_tinysvcmdns; +#ifdef CONFIG_HAVE_DNS_SD_H +extern mdns_backend mdns_dns_sd; +#endif + static mdns_backend *mdns_backends[] = { #ifdef CONFIG_AVAHI &mdns_avahi, +#endif +#ifdef CONFIG_HAVE_DNS_SD_H + &mdns_dns_sd, #endif &mdns_external_avahi, &mdns_external_dns_sd, diff --git a/mdns_dns_sd.c b/mdns_dns_sd.c new file mode 100644 index 00000000..35257412 --- /dev/null +++ b/mdns_dns_sd.c @@ -0,0 +1,98 @@ +/* + * Embedded dns-sd client. This file is part of Shairport. + * Copyright (c) Paul Lietar 2013 + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "mdns.h" +#include "common.h" + +static DNSServiceRef service; + +static int mdns_dns_sd_register(char *apname, int port) { + const char *record[] = { MDNS_RECORD, NULL }; + uint16_t length = 0; + + // Concatenate string contained i record into buf. + + for (const char **field = record; *field; field ++) + { + length += strlen(*field) + 1; // One byte for length each time + } + + char *buf = malloc(length * sizeof(char)); + if (buf == NULL) + { + warn("dns_sd: buffer record allocation failed"); + return -1; + } + + char *p = buf; + + for (const char **field = record; *field; field ++) + { + char * newp = stpcpy(p + 1, *field); + *p = newp - p - 1; + p = newp; + } + + DNSServiceErrorType error; + error = DNSServiceRegister(&service, + 0, + kDNSServiceInterfaceIndexAny, + apname, + "_raop._tcp", + "", + NULL, + htons((uint16_t)port), + length, + buf, + NULL, + NULL); + + free(buf); + + if (error == kDNSServiceErr_NoError) + return 0; + else + { + warn("dns-sd: DNSServiceRegister error %d", error); + return -1; + } +} + +static void mdns_dns_sd_unregister(void) { + if (service) + { + DNSServiceRefDeallocate(service); + service = NULL; + } +} + +mdns_backend mdns_dns_sd = { + .name = "dns-sd", + .mdns_register = mdns_dns_sd_register, + .mdns_unregister = mdns_dns_sd_unregister +};