* 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "dnssd.h"
#include "dnssdint.h"
#include "global.h"
#define MAX_DEVICEID 18
#define MAX_SERVNAME 256
-#ifndef WIN32
-# include <dns_sd.h>
-# define DNSSD_STDCALL
-#else
-# include <stdint.h>
-# if !defined(EFI32) && !defined(EFI64)
-# define DNSSD_STDCALL __stdcall
+#define USE_LIBDL (defined(HAVE_LIBDL) && !defined(__APPLE__))
+
+#if defined(WIN32) || USE_LIBDL
+# ifdef WIN32
+# include <stdint.h>
+# if !defined(EFI32) && !defined(EFI64)
+# define DNSSD_STDCALL __stdcall
+# else
+# define DNSSD_STDCALL
+# endif
# else
+# include <dlfcn.h>
# define DNSSD_STDCALL
# endif
const char *domain,
void *context
);
+
+#else
+# include <dns_sd.h>
+# define DNSSD_STDCALL
#endif
typedef DNSServiceErrorType (DNSSD_STDCALL *DNSServiceRegister_t)
struct dnssd_s {
#ifdef WIN32
HMODULE module;
+#elif USE_LIBDL
+ void *module;
#endif
DNSServiceRegister_t DNSServiceRegister;
TXTRecordGetBytesPtr_t TXTRecordGetBytesPtr;
TXTRecordDeallocate_t TXTRecordDeallocate;
- char hwaddr[MAX_HWADDR_LEN];
- int hwaddrlen;
-
DNSServiceRef raopService;
DNSServiceRef airplayService;
};
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) {
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;
dnssd->TXTRecordDeallocate = &TXTRecordDeallocate;
#endif
- memcpy(dnssd->hwaddr, hwaddr, hwaddrlen);
- dnssd->hwaddrlen = hwaddrlen;
-
return 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);
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;
}
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];
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;