X-Git-Url: https://git.piment-noir.org/?p=deb_shairplay.git;a=blobdiff_plain;f=src%2Flib%2Fdnssd.c;h=4859e3239c7aa569109a7d27933d4c67508fbb29;hp=96e32dc7d561902a76f17fabcf7efb3fcfa9ba8f;hb=53aa68520dec5dcdb1b2eed8bebeb84be4cd357b;hpb=1b4a582b04fc39d9d4d930acb4d0803bdedfb32e diff --git a/src/lib/dnssd.c b/src/lib/dnssd.c index 96e32dc..4859e32 100644 --- a/src/lib/dnssd.c +++ b/src/lib/dnssd.c @@ -1,8 +1,34 @@ +/** + * Copyright (C) 2011-2012 Juho Vähä-Herttua + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +/* These defines allow us to compile on iOS */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif +#ifndef __has_extension +# define __has_extension __has_feature +#endif + #include #include #include #include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "dnssd.h" #include "dnssdint.h" #include "global.h" @@ -12,14 +38,19 @@ #define MAX_DEVICEID 18 #define MAX_SERVNAME 256 -#ifndef WIN32 -# include -#else -# include -# if !defined(EFI32) && !defined(EFI64) -# define DNSSD_API __stdcall +#define USE_LIBDL (defined(HAVE_LIBDL) && !defined(__APPLE__)) + +#if defined(WIN32) || USE_LIBDL +# ifdef WIN32 +# include +# if !defined(EFI32) && !defined(EFI64) +# define DNSSD_STDCALL __stdcall +# else +# define DNSSD_STDCALL +# endif # else -# define DNSSD_API +# include +# define DNSSD_STDCALL # endif typedef struct _DNSServiceRef_t *DNSServiceRef; @@ -28,7 +59,7 @@ typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignmen typedef uint32_t DNSServiceFlags; typedef int32_t DNSServiceErrorType; -typedef void (DNSSD_API *DNSServiceRegisterReply) +typedef void (DNSSD_STDCALL *DNSServiceRegisterReply) ( DNSServiceRef sdRef, DNSServiceFlags flags, @@ -38,9 +69,13 @@ typedef void (DNSSD_API *DNSServiceRegisterReply) const char *domain, void *context ); + +#else +# include +# define DNSSD_STDCALL #endif -typedef DNSServiceErrorType (DNSSD_API *DNSServiceRegister_t) +typedef DNSServiceErrorType (DNSSD_STDCALL *DNSServiceRegister_t) ( DNSServiceRef *sdRef, DNSServiceFlags flags, @@ -55,28 +90,30 @@ typedef DNSServiceErrorType (DNSSD_API *DNSServiceRegister_t) DNSServiceRegisterReply callBack, void *context ); -typedef void (DNSSD_API *DNSServiceRefDeallocate_t)(DNSServiceRef sdRef); -typedef void (DNSSD_API *TXTRecordCreate_t) +typedef void (DNSSD_STDCALL *DNSServiceRefDeallocate_t)(DNSServiceRef sdRef); +typedef void (DNSSD_STDCALL *TXTRecordCreate_t) ( TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer ); -typedef void (DNSSD_API *TXTRecordDeallocate_t)(TXTRecordRef *txtRecord); -typedef DNSServiceErrorType (DNSSD_API *TXTRecordSetValue_t) +typedef void (DNSSD_STDCALL *TXTRecordDeallocate_t)(TXTRecordRef *txtRecord); +typedef DNSServiceErrorType (DNSSD_STDCALL *TXTRecordSetValue_t) ( TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value ); -typedef uint16_t (DNSSD_API *TXTRecordGetLength_t)(const TXTRecordRef *txtRecord); -typedef const void * (DNSSD_API *TXTRecordGetBytesPtr_t)(const TXTRecordRef *txtRecord); +typedef uint16_t (DNSSD_STDCALL *TXTRecordGetLength_t)(const TXTRecordRef *txtRecord); +typedef const void * (DNSSD_STDCALL *TXTRecordGetBytesPtr_t)(const TXTRecordRef *txtRecord); struct dnssd_s { #ifdef WIN32 HMODULE module; +#elif USE_LIBDL + void *module; #endif DNSServiceRegister_t DNSServiceRegister; @@ -87,9 +124,6 @@ struct dnssd_s { TXTRecordGetBytesPtr_t TXTRecordGetBytesPtr; TXTRecordDeallocate_t TXTRecordDeallocate; - char hwaddr[MAX_HWADDR_LEN]; - int hwaddrlen; - DNSServiceRef raopService; DNSServiceRef airplayService; }; @@ -97,15 +131,11 @@ struct dnssd_s { dnssd_t * -dnssd_init(const char *hwaddr, int hwaddrlen, int *error) +dnssd_init(int *error) { dnssd_t *dnssd; if (error) *error = DNSSD_ERROR_NOERROR; - if (hwaddrlen > MAX_HWADDR_LEN) { - if (error) *error = DNSSD_ERROR_HWADDRLEN; - return NULL; - } dnssd = calloc(1, sizeof(dnssd_t)); if (!dnssd) { @@ -136,6 +166,29 @@ dnssd_init(const char *hwaddr, int hwaddrlen, int *error) free(dnssd); return NULL; } +#elif USE_LIBDL + dnssd->module = dlopen("libdns_sd.so", RTLD_LAZY); + if (!dnssd->module) { + if (error) *error = DNSSD_ERROR_LIBNOTFOUND; + free(dnssd); + return NULL; + } + dnssd->DNSServiceRegister = (DNSServiceRegister_t)dlsym(dnssd->module, "DNSServiceRegister"); + dnssd->DNSServiceRefDeallocate = (DNSServiceRefDeallocate_t)dlsym(dnssd->module, "DNSServiceRefDeallocate"); + dnssd->TXTRecordCreate = (TXTRecordCreate_t)dlsym(dnssd->module, "TXTRecordCreate"); + dnssd->TXTRecordSetValue = (TXTRecordSetValue_t)dlsym(dnssd->module, "TXTRecordSetValue"); + dnssd->TXTRecordGetLength = (TXTRecordGetLength_t)dlsym(dnssd->module, "TXTRecordGetLength"); + dnssd->TXTRecordGetBytesPtr = (TXTRecordGetBytesPtr_t)dlsym(dnssd->module, "TXTRecordGetBytesPtr"); + dnssd->TXTRecordDeallocate = (TXTRecordDeallocate_t)dlsym(dnssd->module, "TXTRecordDeallocate"); + + if (!dnssd->DNSServiceRegister || !dnssd->DNSServiceRefDeallocate || !dnssd->TXTRecordCreate || + !dnssd->TXTRecordSetValue || !dnssd->TXTRecordGetLength || !dnssd->TXTRecordGetBytesPtr || + !dnssd->TXTRecordDeallocate) { + if (error) *error = DNSSD_ERROR_PROCNOTFOUND; + dlclose(dnssd->module); + free(dnssd); + return NULL; + } #else dnssd->DNSServiceRegister = &DNSServiceRegister; dnssd->DNSServiceRefDeallocate = &DNSServiceRefDeallocate; @@ -146,9 +199,6 @@ dnssd_init(const char *hwaddr, int hwaddrlen, int *error) dnssd->TXTRecordDeallocate = &TXTRecordDeallocate; #endif - memcpy(dnssd->hwaddr, hwaddr, hwaddrlen); - dnssd->hwaddrlen = hwaddrlen; - return dnssd; } @@ -158,19 +208,23 @@ dnssd_destroy(dnssd_t *dnssd) if (dnssd) { #ifdef WIN32 FreeLibrary(dnssd->module); +#elif USE_LIBDL + dlclose(dnssd->module); #endif free(dnssd); } } int -dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port) +dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port, const char *hwaddr, int hwaddrlen, int password) { TXTRecordRef txtRecord; char servname[MAX_SERVNAME]; int ret; assert(dnssd); + assert(name); + assert(hwaddr); dnssd->TXTRecordCreate(&txtRecord, 0, NULL); dnssd->TXTRecordSetValue(&txtRecord, "txtvers", strlen(RAOP_TXTVERS), RAOP_TXTVERS); @@ -181,16 +235,20 @@ dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port) dnssd->TXTRecordSetValue(&txtRecord, "da", strlen(RAOP_DA), RAOP_DA); dnssd->TXTRecordSetValue(&txtRecord, "sr", strlen(RAOP_SR), RAOP_SR); dnssd->TXTRecordSetValue(&txtRecord, "ss", strlen(RAOP_SS), RAOP_SS); - dnssd->TXTRecordSetValue(&txtRecord, "pw", strlen(RAOP_PW), RAOP_PW); + if (password) { + dnssd->TXTRecordSetValue(&txtRecord, "pw", strlen("true"), "true"); + } else { + dnssd->TXTRecordSetValue(&txtRecord, "pw", strlen("false"), "false"); + } dnssd->TXTRecordSetValue(&txtRecord, "vn", strlen(RAOP_VN), RAOP_VN); dnssd->TXTRecordSetValue(&txtRecord, "tp", strlen(RAOP_TP), RAOP_TP); dnssd->TXTRecordSetValue(&txtRecord, "md", strlen(RAOP_MD), RAOP_MD); dnssd->TXTRecordSetValue(&txtRecord, "vs", strlen(GLOBAL_VERSION), GLOBAL_VERSION); - dnssd->TXTRecordSetValue(&txtRecord, "am", strlen(RAOP_AM), RAOP_AM); - dnssd->TXTRecordSetValue(&txtRecord, "sf", strlen(RAOP_SF), RAOP_SF); + dnssd->TXTRecordSetValue(&txtRecord, "sm", strlen(RAOP_SM), RAOP_SM); + dnssd->TXTRecordSetValue(&txtRecord, "ek", strlen(RAOP_EK), RAOP_EK); /* Convert hardware address to string */ - ret = utils_hwaddr_raop(servname, sizeof(servname), dnssd->hwaddr, dnssd->hwaddrlen); + ret = utils_hwaddr_raop(servname, sizeof(servname), hwaddr, hwaddrlen); if (ret < 0) { /* FIXME: handle better */ return -1; @@ -220,7 +278,7 @@ dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port) } int -dnssd_register_airplay(dnssd_t *dnssd, const char *name, unsigned short port) +dnssd_register_airplay(dnssd_t *dnssd, const char *name, unsigned short port, const char *hwaddr, int hwaddrlen) { TXTRecordRef txtRecord; char deviceid[3*MAX_HWADDR_LEN]; @@ -228,9 +286,11 @@ dnssd_register_airplay(dnssd_t *dnssd, const char *name, unsigned short port) int ret; assert(dnssd); + assert(name); + assert(hwaddr); /* Convert hardware address to string */ - ret = utils_hwaddr_airplay(deviceid, sizeof(deviceid), dnssd->hwaddr, dnssd->hwaddrlen); + ret = utils_hwaddr_airplay(deviceid, sizeof(deviceid), hwaddr, hwaddrlen); if (ret < 0) { /* FIXME: handle better */ return -1;