Linux support for Zeroconf using Avahi over DBus.
This commit is contained in:
parent
135b32642e
commit
48bf42b2a5
|
@ -630,6 +630,36 @@ if(HAVE_DBUS)
|
|||
|
||||
# Gnome Screensaver DBus interface
|
||||
list(APPEND SOURCES ui/dbusscreensaver.cpp)
|
||||
|
||||
if(HAVE_REMOTE)
|
||||
# TODO: Use CMake macro when it supports -i
|
||||
find_program(QDBUSXML2CPP qdbusxml2cpp)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.h
|
||||
COMMAND ${QDBUSXML2CPP}
|
||||
dbus/org.freedesktop.Avahi.EntryGroup.xml
|
||||
-p ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup
|
||||
-i dbus/metatypes.h
|
||||
DEPENDS dbus/org.freedesktop.Avahi.EntryGroup.xml
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
list(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.h)
|
||||
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahientrygroup.cpp)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.h
|
||||
COMMAND ${QDBUSXML2CPP}
|
||||
dbus/org.freedesktop.Avahi.Server.xml
|
||||
-p ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver
|
||||
-i dbus/metatypes.h
|
||||
DEPENDS dbus/org.freedesktop.Avahi.Server.xml
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
list(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.h)
|
||||
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dbus/avahiserver.cpp)
|
||||
endif(HAVE_REMOTE)
|
||||
endif(HAVE_DBUS)
|
||||
|
||||
# Libgpod device backend
|
||||
|
@ -727,6 +757,10 @@ if(HAVE_REMOTE)
|
|||
if(APPLE)
|
||||
list(APPEND SOURCES remote/bonjour.mm)
|
||||
endif(APPLE)
|
||||
|
||||
if(HAVE_DBUS)
|
||||
list(APPEND SOURCES remote/avahi.cpp)
|
||||
endif(HAVE_DBUS)
|
||||
endif(HAVE_REMOTE)
|
||||
|
||||
# OS-specific sources that should be searched for translatable strings even
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
|
||||
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
|
||||
<!DOCTYPE node SYSTEM "introspect.dtd">
|
||||
|
||||
<!--
|
||||
This file is part of avahi.
|
||||
|
||||
avahi 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 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
avahi 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 Lesser General Public
|
||||
License along with avahi; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
-->
|
||||
|
||||
<node>
|
||||
|
||||
<interface name="org.freedesktop.Avahi.EntryGroup">
|
||||
<method name="Free"/>
|
||||
<method name="Commit"/>
|
||||
<method name="Reset"/>
|
||||
|
||||
<method name="GetState">
|
||||
<arg name="state" type="i" direction="out"/>
|
||||
</method>
|
||||
|
||||
<signal name="StateChanged">
|
||||
<arg name="state" type="i"/>
|
||||
<arg name="error" type="s"/>
|
||||
</signal>
|
||||
|
||||
<method name="IsEmpty">
|
||||
<arg name="empty" type="b" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="AddService">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="type" type="s" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="host" type="s" direction="in"/>
|
||||
<arg name="port" type="q" direction="in"/>
|
||||
<arg name="txt" type="aay" direction="in"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.In8"
|
||||
value="QList<QByteArray>" />
|
||||
</method>
|
||||
|
||||
<method name="AddServiceSubtype">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="type" type="s" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="subtype" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="UpdateServiceTxt">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="type" type="s" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="txt" type="aay" direction="in"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.In6"
|
||||
value="QList<QByteArray>" />
|
||||
</method>
|
||||
|
||||
<method name="AddAddress">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="address" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="AddRecord">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="clazz" type="q" direction="in"/>
|
||||
<arg name="type" type="q" direction="in"/>
|
||||
<arg name="ttl" type="u" direction="in"/>
|
||||
<arg name="rdata" type="ay" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +1,218 @@
|
|||
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
|
||||
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
|
||||
<!DOCTYPE node SYSTEM "introspect.dtd">
|
||||
|
||||
<!--
|
||||
This file is part of avahi.
|
||||
|
||||
avahi 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 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
avahi 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 Lesser General Public
|
||||
License along with avahi; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
-->
|
||||
|
||||
<node>
|
||||
|
||||
<interface name="org.freedesktop.Avahi.Server">
|
||||
|
||||
<method name="GetVersionString">
|
||||
<arg name="version" type="s" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="GetAPIVersion">
|
||||
<arg name="version" type="u" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="GetHostName">
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="SetHostName">
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="GetHostNameFqdn">
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="GetDomainName">
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="IsNSSSupportAvailable">
|
||||
<arg name="yes" type="b" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="GetState">
|
||||
<arg name="state" type="i" direction="out"/>
|
||||
</method>
|
||||
|
||||
<signal name="StateChanged">
|
||||
<arg name="state" type="i"/>
|
||||
<arg name="error" type="s"/>
|
||||
</signal>
|
||||
|
||||
<method name="GetLocalServiceCookie">
|
||||
<arg name="cookie" type="u" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="GetAlternativeHostName">
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="GetAlternativeServiceName">
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="GetNetworkInterfaceNameByIndex">
|
||||
<arg name="index" type="i" direction="in"/>
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="GetNetworkInterfaceIndexByName">
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="index" type="i" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="ResolveHostName">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="aprotocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="interface" type="i" direction="out"/>
|
||||
<arg name="protocol" type="i" direction="out"/>
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
<arg name="aprotocol" type="i" direction="out"/>
|
||||
<arg name="address" type="s" direction="out"/>
|
||||
<arg name="flags" type="u" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="ResolveAddress">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="address" type="s" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="interface" type="i" direction="out"/>
|
||||
<arg name="protocol" type="i" direction="out"/>
|
||||
<arg name="aprotocol" type="i" direction="out"/>
|
||||
<arg name="address" type="s" direction="out"/>
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
<arg name="flags" type="u" direction="out"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
Disabled as it breaks the code generation due to its _11_ parameters.
|
||||
<method name="ResolveService">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="type" type="s" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="aprotocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="interface" type="i" direction="out"/>
|
||||
<arg name="protocol" type="i" direction="out"/>
|
||||
<arg name="name" type="s" direction="out"/>
|
||||
<arg name="type" type="s" direction="out"/>
|
||||
<arg name="domain" type="s" direction="out"/>
|
||||
<arg name="host" type="s" direction="out"/>
|
||||
<arg name="aprotocol" type="i" direction="out"/>
|
||||
<arg name="address" type="s" direction="out"/>
|
||||
<arg name="port" type="q" direction="out"/>
|
||||
<arg name="txt" type="aay" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out9"
|
||||
value="QList<QByteArray>" />
|
||||
<arg name="flags" type="u" direction="out"/>
|
||||
</method>
|
||||
-->
|
||||
|
||||
<method name="EntryGroupNew">
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="DomainBrowserNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="btype" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="ServiceTypeBrowserNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="ServiceBrowserNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="type" type="s" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="ServiceResolverNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="type" type="s" direction="in"/>
|
||||
<arg name="domain" type="s" direction="in"/>
|
||||
<arg name="aprotocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="HostNameResolverNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="aprotocol" type="i" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="AddressResolverNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="address" type="s" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="RecordBrowserNew">
|
||||
<arg name="interface" type="i" direction="in"/>
|
||||
<arg name="protocol" type="i" direction="in"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="clazz" type="q" direction="in"/>
|
||||
<arg name="type" type="q" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
|
||||
</interface>
|
||||
</node>
|
|
@ -80,6 +80,7 @@ using boost::scoped_ptr;
|
|||
#include "core/mpris_common.h"
|
||||
#include "core/mpris.h"
|
||||
#include "core/mpris2.h"
|
||||
#include "dbus/metatypes.h"
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusConnection>
|
||||
#include <QImage>
|
||||
|
@ -310,8 +311,9 @@ int main(int argc, char *argv[]) {
|
|||
qDBusRegisterMetaType<QImage>();
|
||||
qDBusRegisterMetaType<TrackMetadata>();
|
||||
qDBusRegisterMetaType<TrackIds>();
|
||||
qDBusRegisterMetaType<QList<QByteArray> >();
|
||||
|
||||
// Create the session bus here so it's sure to live in the main thread
|
||||
// Create the session bus here so it's sure to live in the main thread.
|
||||
QDBusConnection::sessionBus();
|
||||
|
||||
mpris::ArtLoader art_loader;
|
||||
|
@ -323,6 +325,10 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_REMOTE
|
||||
#ifdef HAVE_DBUS
|
||||
// Create the system bus here so it's sure to live in the main thread.
|
||||
QDBusConnection::systemBus();
|
||||
#endif
|
||||
Zeroconf* zeroconf = Zeroconf::GetZeroconf();
|
||||
if (zeroconf) {
|
||||
HttpServer* server = new HttpServer(&player);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#include "avahi.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QHostInfo>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
#include "dbus/avahientrygroup.h"
|
||||
#include "dbus/avahiserver.h"
|
||||
|
||||
void Avahi::Publish(
|
||||
const QString& domain, const QString& type, const QString& name, quint16 port) {
|
||||
QtConcurrent::run(Avahi::SyncPublish, domain, type, name, port);
|
||||
}
|
||||
|
||||
void Avahi::SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port) {
|
||||
OrgFreedesktopAvahiServerInterface server_interface(
|
||||
"org.freedesktop.Avahi",
|
||||
"/",
|
||||
QDBusConnection::systemBus());
|
||||
|
||||
QDBusPendingReply<QDBusObjectPath> reply = server_interface.EntryGroupNew();
|
||||
reply.waitForFinished();
|
||||
|
||||
OrgFreedesktopAvahiEntryGroupInterface entry_group_interface(
|
||||
"org.freedesktop.Avahi",
|
||||
reply.value().path(),
|
||||
QDBusConnection::systemBus());
|
||||
|
||||
QDBusPendingReply<> add_reply = entry_group_interface.AddService(
|
||||
-1, // Interface (Unspecified, ie. all interfaces)
|
||||
-1, // Protocol (Unspecified, ie. IPv4 & IPv6)
|
||||
0, // Flags
|
||||
name, // Service name
|
||||
type, // Service type
|
||||
domain, // Domain, ie. local
|
||||
QString::null, // Hostname (Avahi fills it if it's null)
|
||||
port, // Port
|
||||
QList<QByteArray>()); // TXT record
|
||||
add_reply.waitForFinished();
|
||||
|
||||
QDBusPendingReply<> commit_reply = entry_group_interface.Commit();
|
||||
commit_reply.waitForFinished();
|
||||
if (commit_reply.isValid()) {
|
||||
qDebug() << "Remote interface published on Avahi";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef AVAHI_H
|
||||
#define AVAHI_H
|
||||
|
||||
#include "zeroconf.h"
|
||||
|
||||
class Avahi : public Zeroconf {
|
||||
public:
|
||||
virtual void Publish(
|
||||
const QString& domain, const QString& type, const QString& name, quint16 port);
|
||||
|
||||
private:
|
||||
static void SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,9 +1,15 @@
|
|||
#include "zeroconf.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include "bonjour.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include "avahi.h"
|
||||
#endif
|
||||
|
||||
Zeroconf* Zeroconf::instance_ = NULL;
|
||||
|
||||
Zeroconf* Zeroconf::GetZeroconf() {
|
||||
|
@ -11,6 +17,10 @@ Zeroconf* Zeroconf::GetZeroconf() {
|
|||
#ifdef Q_OS_DARWIN
|
||||
return new Bonjour();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
return new Avahi();
|
||||
#endif
|
||||
}
|
||||
|
||||
return instance_;
|
||||
|
|
Loading…
Reference in New Issue