Add zeroconf/mdns support
This commit is contained in:
parent
aae15e3c90
commit
c53b19c039
58
libs/ardour/ardour/zeroconf.h
Normal file
58
libs/ardour/ardour/zeroconf.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Robin Gareus <robin@gareus.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dns_sd.h>
|
||||
#include <glibmm/iochannel.h>
|
||||
#include <glibmm/main.h>
|
||||
#endif
|
||||
|
||||
#include "ardour/libardour_visibility.h"
|
||||
#include "ardour/system_exec.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class LIBARDOUR_API ZeroConf
|
||||
{
|
||||
public:
|
||||
ZeroConf (std::string const& type = "_osc._udp", uint16_t port = 3819, std::string const& host = "");
|
||||
~ZeroConf ();
|
||||
|
||||
private:
|
||||
bool start ();
|
||||
void stop ();
|
||||
|
||||
std::string _type;
|
||||
uint16_t _port;
|
||||
std::string _host;
|
||||
|
||||
#ifdef __APPLE__
|
||||
static gboolean event (GIOChannel*, GIOCondition, gpointer);
|
||||
|
||||
DNSServiceRef _ref;
|
||||
guint _source_id;
|
||||
GIOChannel* _gio_channel;
|
||||
#else
|
||||
SystemExec* _avahi;
|
||||
#endif
|
||||
};
|
||||
|
||||
}; // namespace ARDOUR
|
@ -282,7 +282,8 @@ libardour_sources = [
|
||||
'vca_manager.cc',
|
||||
'video_tools_paths.cc',
|
||||
'vumeterdsp.cc',
|
||||
'worker.cc'
|
||||
'worker.cc',
|
||||
'zeroconf.cc'
|
||||
]
|
||||
|
||||
def options(opt):
|
||||
|
166
libs/ardour/zeroconf.cc
Normal file
166
libs/ardour/zeroconf.cc
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Robin Gareus <robin@gareus.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/file_utils.h"
|
||||
|
||||
#include "ardour/filesystem_paths.h"
|
||||
#include "ardour/zeroconf.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
|
||||
ZeroConf::ZeroConf (std::string const& type, uint16_t port, std::string const& host)
|
||||
: _type (type)
|
||||
, _port (port)
|
||||
, _host (host)
|
||||
#ifdef __APPLE__
|
||||
, _source_id (0)
|
||||
, _gio_channel (NULL)
|
||||
#else
|
||||
, _avahi (NULL)
|
||||
#endif
|
||||
{
|
||||
start ();
|
||||
}
|
||||
|
||||
ZeroConf::~ZeroConf ()
|
||||
{
|
||||
stop ();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
void
|
||||
ZeroConf::stop ()
|
||||
{
|
||||
if (_gio_channel) {
|
||||
g_source_remove (_source_id);
|
||||
g_io_channel_unref (_gio_channel);
|
||||
}
|
||||
DNSServiceRefDeallocate (_ref);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_callback (DNSServiceRef sdref,
|
||||
DNSServiceFlags flags,
|
||||
DNSServiceErrorType errorCode,
|
||||
const char* name,
|
||||
const char* regtype,
|
||||
const char* domain, void* context)
|
||||
{
|
||||
if (errorCode == kDNSServiceErr_NoError) {
|
||||
PBD::info << string_compose (_("ZeroConf registered: %1 %2 %3"), name, regtype, domain) << endmsg;
|
||||
} else {
|
||||
PBD::info << _("ZeroConf registration failed") << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
ZeroConf::event (GIOChannel* source,
|
||||
GIOCondition condition,
|
||||
gpointer data)
|
||||
{
|
||||
ZeroConf* self = reinterpret_cast<ZeroConf*> (data);
|
||||
// assert (_fd == g_io_channel_unix_get_fd (source));
|
||||
|
||||
if (condition & ~G_IO_IN) {
|
||||
/* remove on error */
|
||||
return false;
|
||||
} else {
|
||||
if (DNSServiceProcessResult (self->_ref) != kDNSServiceErr_NoError) {
|
||||
/* ZeroConf Error in data callback */
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ZeroConf::start ()
|
||||
{
|
||||
if (kDNSServiceErr_NoError != DNSServiceRegister (&_ref, /*flags*/ 0, /*interfaceIndex*/ 0, /*name*/ NULL, _type.c_str (),
|
||||
/*domain*/ NULL, _host.empty () ? NULL : _host.c_str (), g_htons (_port),
|
||||
/*txtlen*/ 0, /*TXT*/ NULL, dns_callback, this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = DNSServiceRefSockFD (_ref);
|
||||
_gio_channel = g_io_channel_unix_new (fd);
|
||||
_source_id = g_io_add_watch (_gio_channel, (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP), ZeroConf::event, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined PLATFORM_WINDOWS
|
||||
|
||||
/* in theory dns_sd API also works on Windows 10+
|
||||
* windns.h and dnsapi.dll
|
||||
*/
|
||||
|
||||
bool
|
||||
ZeroConf::start ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ZeroConf::stop ()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
ZeroConf::start ()
|
||||
{
|
||||
std::string avahi_exec;
|
||||
|
||||
PBD::Searchpath sp (ARDOUR::ardour_dll_directory ());
|
||||
if (!PBD::find_file (sp, "ardour-avahi.sh", avahi_exec)) {
|
||||
PBD::warning << "ardour-avahi.sh was not found." << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
char** argp;
|
||||
char tmp[128];
|
||||
argp = (char**)calloc (5, sizeof (char*));
|
||||
argp[0] = strdup (avahi_exec.c_str ());
|
||||
snprintf (tmp, sizeof (tmp), "%d", _port);
|
||||
argp[1] = strdup (tmp);
|
||||
argp[2] = strdup (_type.c_str ());
|
||||
snprintf (tmp, sizeof (tmp), "%d", getpid ());
|
||||
argp[3] = strdup (tmp);
|
||||
argp[4] = 0;
|
||||
|
||||
_avahi = new ARDOUR::SystemExec (avahi_exec, argp);
|
||||
if (_avahi->start (SystemExec::ShareWithParent)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ZeroConf::stop ()
|
||||
{
|
||||
ARDOUR::SystemExec* tmp = _avahi;
|
||||
_avahi = 0;
|
||||
delete tmp;
|
||||
}
|
||||
#endif
|
24
tools/avahi.sh
Executable file
24
tools/avahi.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
test -n "`which avahi-publish`"
|
||||
test -n "`which tail`"
|
||||
|
||||
PORT=$1
|
||||
TYPE=$2
|
||||
test -n "$PORT"
|
||||
test -n "$TYPE"
|
||||
|
||||
if test -n "$3"; then
|
||||
PARENT_PID=$3
|
||||
else
|
||||
PARENT_PID=$$
|
||||
fi
|
||||
|
||||
avahi-publish -s Ardour-$PARENT_PID "$TYPE" "$PORT" &
|
||||
CHILD_PID=$!
|
||||
|
||||
trap "kill -- $CHILD_PID" EXIT
|
||||
|
||||
tail --pid=$PARENT_PID -f 2>/dev/null
|
@ -506,6 +506,9 @@ EOF
|
||||
chmod +x $APPLIB/ardour-util.sh
|
||||
fi
|
||||
|
||||
cp $BUILD_ROOT/avahi.sh $APPLIB/ardour-avahi.sh
|
||||
chmod +x $APPLIB/ardour-avahi.sh
|
||||
|
||||
OURLIBDIR=$BUILD_ROOT/libs
|
||||
OURLIBS=$OURLIBDIR/ctrl-interface/midi_surface:$OURLIBDIR/ctrl-interface/control_protocol:$OURLIBDIR/ardour:$OURLIBDIR/midi++2:$OURLIBDIR/pbd:$OURLIBDIR/gtkmm2ext:$OURLIBDIR/glibmm2:$OURLIBDIR/canvas:$OURLIBDIR/widgets:$OURLIBDIR/waveview:$OURLIBDIR/evoral:$OURLIBDIR/evoral/src/libsmf:$OURLIBDIR/audiographer:$OURLIBDIR/temporal:$OURLIBDIR/libltc:$OURLIBDIR/qm-dsp:$OURLIBDIR/ardouralsautil:$OURLIBDIR/ptformat:$BUILD_ROOT/gtk2_ardour
|
||||
|
||||
|
7
wscript
7
wscript
@ -10,6 +10,7 @@ import platform as PLATFORM
|
||||
from waflib.Tools import winres
|
||||
from waflib.Build import Context
|
||||
from waflib.Build import BuildContext
|
||||
import waflib.Utils as Utils
|
||||
|
||||
# Fixup OSX 10.5/10.6 builds
|
||||
# prefer gcc, g++ 4.x over ancient clang-1.5
|
||||
@ -1619,6 +1620,12 @@ def build(bld):
|
||||
bld.recurse('tools/sanity_check')
|
||||
bld.recurse('tools/gccabicheck')
|
||||
|
||||
obj = bld(features = 'subst')
|
||||
obj.source = 'tools/avahi.sh'
|
||||
obj.target = 'libs/ardour-avahi.sh'
|
||||
obj.chmod = Utils.O755
|
||||
obj.install_path = bld.env['LIBDIR']
|
||||
|
||||
bld.recurse('libs/clearlooks-newer')
|
||||
|
||||
for i in children:
|
||||
|
Loading…
Reference in New Issue
Block a user