1 /*
2 * Copyright 2003-2021 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "Init.hxx"
21 #include "Compat.hxx"
22 #include "thread/Mutex.hxx"
23 #include "util/RuntimeError.hxx"
24
25 #include <upnptools.h>
26 #ifdef USING_PUPNP
27 # include <ixml.h>
28 #endif
29
30 #include <cassert>
31
32 static Mutex upnp_init_mutex;
33 static unsigned upnp_ref;
34
35 static void
DoInit(const char * iface)36 DoInit(const char* iface)
37 {
38
39 #ifdef UPNP_ENABLE_IPV6
40 auto code = UpnpInit2(iface, 0);
41 #else
42 auto code = UpnpInit(iface, 0);
43 #endif
44 if (code != UPNP_E_SUCCESS)
45 throw FormatRuntimeError("UpnpInit() failed: %s",
46 UpnpGetErrorMessage(code));
47
48 UpnpSetMaxContentLength(2000*1024);
49
50 #ifdef USING_PUPNP
51 // Servers sometimes make error (e.g.: minidlna returns bad utf-8)
52 ixmlRelaxParser(1);
53 #endif
54 }
55
56 void
UpnpGlobalInit(const char * iface)57 UpnpGlobalInit(const char* iface)
58 {
59 const std::scoped_lock<Mutex> protect(upnp_init_mutex);
60
61 if (upnp_ref == 0)
62 DoInit(iface);
63
64 ++upnp_ref;
65 }
66
67 void
UpnpGlobalFinish()68 UpnpGlobalFinish() noexcept
69 {
70 const std::scoped_lock<Mutex> protect(upnp_init_mutex);
71
72 assert(upnp_ref > 0);
73
74 if (--upnp_ref == 0)
75 UpnpFinish();
76 }
77