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',
|
'vca_manager.cc',
|
||||||
'video_tools_paths.cc',
|
'video_tools_paths.cc',
|
||||||
'vumeterdsp.cc',
|
'vumeterdsp.cc',
|
||||||
'worker.cc'
|
'worker.cc',
|
||||||
|
'zeroconf.cc'
|
||||||
]
|
]
|
||||||
|
|
||||||
def options(opt):
|
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
|
chmod +x $APPLIB/ardour-util.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
cp $BUILD_ROOT/avahi.sh $APPLIB/ardour-avahi.sh
|
||||||
|
chmod +x $APPLIB/ardour-avahi.sh
|
||||||
|
|
||||||
OURLIBDIR=$BUILD_ROOT/libs
|
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
|
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.Tools import winres
|
||||||
from waflib.Build import Context
|
from waflib.Build import Context
|
||||||
from waflib.Build import BuildContext
|
from waflib.Build import BuildContext
|
||||||
|
import waflib.Utils as Utils
|
||||||
|
|
||||||
# Fixup OSX 10.5/10.6 builds
|
# Fixup OSX 10.5/10.6 builds
|
||||||
# prefer gcc, g++ 4.x over ancient clang-1.5
|
# 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/sanity_check')
|
||||||
bld.recurse('tools/gccabicheck')
|
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')
|
bld.recurse('libs/clearlooks-newer')
|
||||||
|
|
||||||
for i in children:
|
for i in children:
|
||||||
|
Loading…
Reference in New Issue
Block a user