aboutsummaryrefslogtreecommitdiffstats
path: root/src/neighbor
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-01-26 11:19:17 +0100
committerMax Kellermann <max@duempel.org>2014-01-26 15:51:33 +0100
commit0b3fbdba87e9ecbfaefab9f71203a1c35f1a8b00 (patch)
tree4e103fbcbea5dd504054f0d60dbc84e83ceed52b /src/neighbor
parent3dad837ca692df4eecee9c16fd9155b4ca23e289 (diff)
downloadmpd-0b3fbdba87e9ecbfaefab9f71203a1c35f1a8b00.tar.gz
mpd-0b3fbdba87e9ecbfaefab9f71203a1c35f1a8b00.tar.xz
mpd-0b3fbdba87e9ecbfaefab9f71203a1c35f1a8b00.zip
neighbor/upnp: UPnP media server discovery
Diffstat (limited to 'src/neighbor')
-rw-r--r--src/neighbor/Registry.cxx4
-rw-r--r--src/neighbor/plugins/UpnpNeighborPlugin.cxx139
-rw-r--r--src/neighbor/plugins/UpnpNeighborPlugin.hxx27
3 files changed, 170 insertions, 0 deletions
diff --git a/src/neighbor/Registry.cxx b/src/neighbor/Registry.cxx
index fc9d05ecf..f6d1f97b3 100644
--- a/src/neighbor/Registry.cxx
+++ b/src/neighbor/Registry.cxx
@@ -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
};
diff --git a/src/neighbor/plugins/UpnpNeighborPlugin.cxx b/src/neighbor/plugins/UpnpNeighborPlugin.cxx
new file mode 100644
index 000000000..253e4c13b
--- /dev/null
+++ b/src/neighbor/plugins/UpnpNeighborPlugin.cxx
@@ -0,0 +1,139 @@
+/*
+ * 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,
+};
diff --git a/src/neighbor/plugins/UpnpNeighborPlugin.hxx b/src/neighbor/plugins/UpnpNeighborPlugin.hxx
new file mode 100644
index 000000000..78e4ccf13
--- /dev/null
+++ b/src/neighbor/plugins/UpnpNeighborPlugin.hxx
@@ -0,0 +1,27 @@
+/*
+ * 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