Commit 0b3fbdba authored by Max Kellermann's avatar Max Kellermann

neighbor/upnp: UPnP media server discovery

parent 3dad837c
......@@ -436,6 +436,15 @@ NEIGHBOR_LIBS = \
$(SMBCLIENT_LIBS) \
libneighbor.a
if HAVE_LIBUPNP
libneighbor_a_SOURCES += \
$(UPNP_SOURCES) \
src/neighbor/plugins/UpnpNeighborPlugin.cxx src/neighbor/plugins/UpnpNeighborPlugin.hxx
NEIGHBOR_LIBS += \
$(EXPAT_LIBS) \
$(UPNP_LIBS)
endif
endif
# database plugins
......@@ -1323,10 +1332,14 @@ if ENABLE_NEIGHBOR_PLUGINS
test_run_neighbor_explorer_SOURCES = \
src/Log.cxx src/LogBackend.cxx \
src/IOThread.cxx \
test/run_neighbor_explorer.cxx
test_run_neighbor_explorer_LDADD = \
$(GLIB_LIBS) \
$(NEIGHBOR_LIBS) \
$(INPUT_LIBS) \
$(ARCHIVE_LIBS) \
libtag.a \
libconf.a \
libevent.a \
libfs.a \
......@@ -1334,6 +1347,16 @@ test_run_neighbor_explorer_LDADD = \
libthread.a \
libutil.a
if HAVE_LIBUPNP
test_run_neighbor_explorer_SOURCES += src/lib/expat/ExpatParser.cxx
endif
if ENABLE_DESPOTIFY
test_run_neighbor_explorer_SOURCES += \
src/lib/despotify/DespotifyUtils.cxx \
src/lib/despotify/DespotifyUtils.hxx
endif
endif
if ENABLE_ARCHIVE
......
......@@ -897,6 +897,9 @@ if test x$enable_neighbor_plugins = xauto; then
if test x$enable_smbclient = xyes; then
enable_neighbor_plugins=yes
fi
if test x$enable_upnp = xyes; then
enable_neighbor_plugins=yes
fi
fi
if test x$enable_neighbor_plugins = xyes; then
......
......@@ -121,6 +121,11 @@ public:
std::list<std::string> &result,
Error &error) const;
gcc_pure
std::string GetURI() const {
return "upnp://" + m_deviceId + "/" + m_serviceType;
}
/** Retrieve the "friendly name" for this server, useful for display. */
const char *getFriendlyName() const {
return m_friendlyName.c_str();
......
......@@ -21,6 +21,7 @@
#include "Registry.hxx"
#include "NeighborPlugin.hxx"
#include "plugins/SmbclientNeighborPlugin.hxx"
#include "plugins/UpnpNeighborPlugin.hxx"
#include <string.h>
......@@ -28,6 +29,9 @@ const NeighborPlugin *const neighbor_plugins[] = {
#ifdef ENABLE_SMBCLIENT
&smbclient_neighbor_plugin,
#endif
#ifdef HAVE_LIBUPNP
&upnp_neighbor_plugin,
#endif
nullptr
};
......
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* http://www.musicpd.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 "config.h"
#include "UpnpNeighborPlugin.hxx"
#include "lib/upnp/Domain.hxx"
#include "lib/upnp/ClientInit.hxx"
#include "lib/upnp/Discovery.hxx"
#include "lib/upnp/ContentDirectoryService.hxx"
#include "neighbor/NeighborPlugin.hxx"
#include "neighbor/Explorer.hxx"
#include "neighbor/Listener.hxx"
#include "neighbor/Info.hxx"
#include "Log.hxx"
class UpnpNeighborExplorer final
: public NeighborExplorer, UPnPDiscoveryListener {
struct Server {
std::string name, comment;
bool alive;
Server(std::string &&_name, std::string &&_comment)
:name(std::move(_name)), comment(std::move(_comment)),
alive(true) {}
Server(const Server &) = delete;
gcc_pure
bool operator==(const Server &other) const {
return name == other.name;
}
gcc_pure
NeighborInfo Export() const {
return { "smb://" + name + "/", comment };
}
};
UPnPDeviceDirectory *discovery;
public:
UpnpNeighborExplorer(NeighborListener &_listener)
:NeighborExplorer(_listener) {}
/* virtual methods from class NeighborExplorer */
virtual bool Open(Error &error) override;
virtual void Close() override;
virtual List GetList() const override;
private:
/* virtual methods from class UPnPDiscoveryListener */
virtual void FoundUPnP(const ContentDirectoryService &service) override;
virtual void LostUPnP(const ContentDirectoryService &service) override;
};
bool
UpnpNeighborExplorer::Open(Error &error)
{
UpnpClient_Handle handle;
if (!UpnpClientGlobalInit(handle, error))
return false;
discovery = new UPnPDeviceDirectory(handle, this);
if (!discovery->Start(error)) {
delete discovery;
UpnpClientGlobalFinish();
return false;
}
return true;
}
void
UpnpNeighborExplorer::Close()
{
delete discovery;
UpnpClientGlobalFinish();
}
NeighborExplorer::List
UpnpNeighborExplorer::GetList() const
{
std::vector<ContentDirectoryService> tmp;
{
Error error;
if (!discovery->getDirServices(tmp, error))
LogError(error);
}
List result;
for (const auto &i : tmp)
result.emplace_front(i.GetURI(), i.getFriendlyName());
return result;
}
void
UpnpNeighborExplorer::FoundUPnP(const ContentDirectoryService &service)
{
const NeighborInfo n(service.GetURI(), service.getFriendlyName());
listener.FoundNeighbor(n);
}
void
UpnpNeighborExplorer::LostUPnP(const ContentDirectoryService &service)
{
const NeighborInfo n(service.GetURI(), service.getFriendlyName());
listener.LostNeighbor(n);
}
static NeighborExplorer *
upnp_neighbor_create(gcc_unused EventLoop &loop,
NeighborListener &listener,
gcc_unused const config_param &param,
gcc_unused Error &error)
{
return new UpnpNeighborExplorer(listener);
}
const NeighborPlugin upnp_neighbor_plugin = {
"upnp",
upnp_neighbor_create,
};
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* http://www.musicpd.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.
*/
#ifndef MPD_NEIGHBOR_UPNP_HXX
#define MPD_NEIGHBOR_UPNP_HXX
struct NeighborPlugin;
extern const NeighborPlugin upnp_neighbor_plugin;
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment