MythTV master
mediaserver.cpp
Go to the documentation of this file.
1
2// Program Name: mediaserver.cpp
3//
4// Purpose - uPnp Media Server main Class
5//
6// Created By : David Blain Created On : Jan. 15, 2007
7// Modified By : Modified On:
8//
10
11#include "libmythbase/mythconfig.h"
12
13// Qt
14#include <QNetworkInterface>
15#include <QNetworkProxy>
16
17// MythTV
18#if CONFIG_LIBDNS_SD
20#endif
22#include "libmythbase/mythdb.h"
26
27// MythBackend
28#include "httpconfig.h"
29#include "internetContent.h"
30#include "mediaserver.h"
31#include "upnpcdsmusic.h"
32#include "upnpcdstv.h"
33#include "upnpcdsvideo.h"
34
35
38//
39// UPnp Class implementaion
40//
43
45//
47
49 m_sSharePath(GetShareDir())
50{
51 LOG(VB_UPNP, LOG_INFO, "MediaServer()");
52}
53
54void MediaServer::Init(bool bIsMaster, bool bDisableUPnp /* = false */)
55{
56 LOG(VB_UPNP, LOG_INFO, "MediaServer::Init(): Begin");
57
58 int nPort = GetMythDB()->GetNumSetting("BackendStatusPort", 6544);
59 int nSSLPort = GetMythDB()->GetNumSetting("BackendSSLPort", nPort + 10);
60 int nWSPort = nPort + 5;
61 // UPNP port is now status port + 6 (default 6550)
62 nPort += 6;
63 nSSLPort += 6;
64
65 auto *pHttpServer = new HttpServer();
66
67 if (!pHttpServer->isListening())
68 {
69 pHttpServer->setProxy(QNetworkProxy::NoProxy);
70 // HTTP
71 if (!pHttpServer->listen(nPort))
72 {
73 LOG(VB_GENERAL, LOG_ERR, "MediaServer: HttpServer Create Error");
74 delete pHttpServer;
75 pHttpServer = nullptr;
76 return;
77 }
78
79#ifndef QT_NO_OPENSSL
80 // HTTPS (SSL)
81 if (!pHttpServer->listen(nSSLPort, true, kSSLServer))
82 {
83 LOG(VB_GENERAL, LOG_ERR, "MediaServer: HttpServer failed to create SSL server");
84 }
85#endif
86 }
87
89
91 {
92 if (!m_webSocketServer->listen(nWSPort))
93 {
94 LOG(VB_GENERAL, LOG_ERR, "MediaServer: WebSocketServer Create Error");
95 }
96 }
97
98 QString sFileName = GetMythDB()->GetSetting("upnpDescXmlPath", m_sSharePath);
99
100 if ( bIsMaster )
101 sFileName += "devicemaster.xml";
102 else
103 sFileName += "deviceslave.xml";
104
105 // ------------------------------------------------------------------
106 // Make sure our device Description is loaded.
107 // ------------------------------------------------------------------
108
109 LOG(VB_UPNP, LOG_INFO,
110 "MediaServer: Loading UPnp Description " + sFileName);
111
112 g_UPnpDeviceDesc.Load( sFileName );
113
114 // ------------------------------------------------------------------
115 // Register Http Server Extensions...
116 // ------------------------------------------------------------------
117
118 LOG(VB_UPNP, LOG_INFO, "MediaServer: Registering Http Server Extensions.");
119
120 auto *pHtmlServer =
121 new HtmlServerExtension(m_sSharePath + "html", "backend_");
122 pHttpServer->RegisterExtension( pHtmlServer );
123 pHttpServer->RegisterExtension( new HttpConfig() );
124 pHttpServer->RegisterExtension( new InternetContent ( m_sSharePath ));
125
126 // ------------------------------------------------------------------
127 // Register Service Types with Scripting Engine
128 //
129 // -=>NOTE: We need to know the actual type at compile time for this
130 // to work, so it needs to be done here. I'm still looking
131 // into ways that we may encapsulate this in the service
132 // classes. - dblain
133 // ------------------------------------------------------------------
134
135
136 if (bDisableUPnp)
137 {
138 LOG(VB_GENERAL, LOG_NOTICE,
139 "*** The UPNP service has been DISABLED with the "
140 "--noupnp option ***");
141 return;
142 }
143
144 QList<QHostAddress> IPAddrList = ServerPool::DefaultListen();
145 if (IPAddrList.contains(QHostAddress(QHostAddress::AnyIPv4)))
146 {
147 IPAddrList.removeAll(QHostAddress(QHostAddress::AnyIPv4));
148 IPAddrList.removeAll(QHostAddress(QHostAddress::AnyIPv6));
149 IPAddrList.append(QNetworkInterface::allAddresses());
150 }
151
152 if (IPAddrList.isEmpty())
153 {
154 LOG(VB_GENERAL, LOG_ERR,
155 "MediaServer: No Listenable IP Addresses found - "
156 "Disabling UPnP");
157 return;
158 }
159
160 // ----------------------------------------------------------------------
161 // Initialize UPnp Stack
162 // ----------------------------------------------------------------------
163
164 if (Initialize( IPAddrList, nPort, pHttpServer ))
165 {
166
167 // ------------------------------------------------------------------
168 // Register any HttpServerExtensions... Only The Master Backend
169 // ------------------------------------------------------------------
170
171 if (bIsMaster)
172 {
173 QString sSourceProtocols = GetSourceProtocolInfos().join(",");
174
175 LOG(VB_UPNP, LOG_INFO, "MediaServer: Registering MS_MediaReceiverRegistrar Service.");
176
178 m_sSharePath ) );
179
180 LOG(VB_UPNP, LOG_INFO, "MediaServer: Registering ConnnectionManager Service.");
181
183 m_sSharePath, sSourceProtocols );
185
186 LOG(VB_UPNP, LOG_INFO, "MediaServer: Registering ContentDirectory Service.");
187
190
191 // ----------------------------------------------------------------
192 // Register CDS Extensions
193 // ----------------------------------------------------------------
194
195 LOG(VB_UPNP, LOG_INFO,
196 "MediaServer: Registering UPnpCDSTv Extension");
197
199
200 LOG(VB_UPNP, LOG_INFO,
201 "MediaServer: Registering UPnpCDSMusic Extension");
202
204
205 LOG(VB_UPNP, LOG_INFO,
206 "MediaServer: Registering UPnpCDSVideo Extension");
207
209 }
210
211#if 0
212 LOG(VB_UPNP, LOG_INFO, "MediaServer::Adding Context Listener");
213
214 gCoreContext->addListener( this );
215#endif
216
217 Start();
218
219#if CONFIG_LIBDNS_SD
220 // advertise using Bonjour
221 if (gCoreContext)
222 {
223 m_bonjour = new BonjourRegister();
224 if (m_bonjour)
225 {
226 QByteArray name("Mythbackend on ");
227 name.append(gCoreContext->GetHostName().toUtf8());
228 QByteArray txt(bIsMaster ? "\x06master" : "\x05slave");
229 m_bonjour->Register(nPort, "_mythbackend._tcp", name, txt);
230 }
231 }
232#endif
233 }
234
235 LOG(VB_UPNP, LOG_INFO, "MediaServer::Init(): End");
236}
237
239//
241
243{
244 // -=>TODO: Need to check to see if calling this more than once is ok.
245
246#if 0
248#endif
249
250 delete m_webSocketServer;
251 delete m_pHttpServer;
252
253#if CONFIG_LIBDNS_SD
254 delete m_bonjour;
255#endif
256}
257
259//
261#if 0
262void MediaServer::customEvent( QEvent *e )
263{
264 if (MythEvent::Type(e->type()) == MythEvent::MythEventMessage)
265 {
266 MythEvent *me = static_cast<MythEvent *>(e);
267 QString message = me->Message();
268
269 //-=>TODO: Need to handle events to notify clients of changes
270 }
271}
272#endif
274//
276
278{
279 m_pUPnpCDS->RegisterExtension( pExtension );
280}
281
283//
285
287{
288 m_pUPnpCDS->UnregisterExtension( pExtension );
289}
void RegisterExtension(HttpServerExtension *pExtension)
Definition: httpserver.cpp:309
void RegisterExtension(UPnpCDSExtension *pExtension)
WebSocketServer * m_webSocketServer
Definition: mediaserver.h:41
UPnpCMGR * m_pUPnpCMGR
Definition: mediaserver.h:46
void Init(bool bIsMaster, bool bDisableUPnp=false)
Definition: mediaserver.cpp:54
~MediaServer() override
void UnregisterExtension(UPnpCDSExtension *pExtension)
QString m_sSharePath
Definition: mediaserver.h:48
UPnpCDS * m_pUPnpCDS
Definition: mediaserver.h:45
QString GetHostName(void)
This class is used as a container for messages.
Definition: mythevent.h:17
const QString & Message() const
Definition: mythevent.h:65
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
static QList< QHostAddress > DefaultListen(void)
Definition: serverpool.cpp:305
bool listen(QList< QHostAddress > addrs, quint16 port, bool requireall=true, PoolServerType type=kTCPServer)
Definition: serverpool.cpp:395
bool isListening(void) const
Definition: serverpool.h:92
void RegisterExtension(UPnpCDSExtension *pExtension)
Definition: upnpcds.cpp:167
void UnregisterExtension(UPnpCDSExtension *pExtension)
Definition: upnpcds.cpp:186
bool Load(const QString &sFileName)
Definition: upnpdevice.cpp:42
static UPnpDevice * RootDevice()
Definition: upnp.h:124
HttpServer * m_pHttpServer
Definition: upnp.h:102
virtual void Start()
Definition: upnp.cpp:144
bool Initialize(int nServicePort, HttpServer *pHttpServer)
Definition: upnp.cpp:74
static UPnpDeviceDesc g_UPnpDeviceDesc
Definition: upnp.h:107
The WebSocket server, which listens for connections.
Definition: websocket.h:39
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythDB * GetMythDB(void)
Definition: mythdb.cpp:51
QString GetShareDir(void)
Definition: mythdirs.cpp:261
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
@ kSSLServer
Definition: serverpool.h:33
QStringList GetSourceProtocolInfos()
Return a QStringList containing the supported Source Protocols.
Definition: upnputil.cpp:69