MythTV  master
mediaserver.cpp
Go to the documentation of this file.
1 // 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"
23 #include "libmythbase/mythdirs.h"
25 #include "libmythupnp/htmlserver.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 
54 void 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
262 void 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
273 //
276 
278 {
279  m_pUPnpCDS->RegisterExtension( pExtension );
280 }
281 
283 //
285 
287 {
288  m_pUPnpCDS->UnregisterExtension( pExtension );
289 }
UPnpCDSExtension
Definition: upnpcds.h:203
mythdb.h
GetSourceProtocolInfos
QStringList GetSourceProtocolInfos()
Return a QStringList containing the supported Source Protocols.
Definition: upnputil.cpp:69
UPnpMSRR
Definition: upnpmsrr.h:27
upnpcdsvideo.h
UPnp::Start
virtual void Start()
Definition: upnp.cpp:144
HttpServer::RegisterExtension
void RegisterExtension(HttpServerExtension *pExtension)
Definition: httpserver.cpp:309
ServerPool::isListening
bool isListening(void) const
Definition: serverpool.h:92
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MediaServer::m_pUPnpCMGR
UPnpCMGR * m_pUPnpCMGR
Definition: mediaserver.h:46
InternetContent
Definition: internetContent.h:28
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
BonjourRegister
Definition: bonjourregister.h:11
MediaServer::RegisterExtension
void RegisterExtension(UPnpCDSExtension *pExtension)
Definition: mediaserver.cpp:277
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:51
mythdirs.h
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
UPnp::Initialize
bool Initialize(int nServicePort, HttpServer *pHttpServer)
Definition: upnp.cpp:74
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
kSSLServer
@ kSSLServer
Definition: serverpool.h:33
upnpcdstv.h
MediaServer::m_sSharePath
QString m_sSharePath
Definition: mediaserver.h:48
httpconfig.h
mythlogging.h
UPnpCDS
Definition: upnpcds.h:282
UPnpCDS::UnregisterExtension
void UnregisterExtension(UPnpCDSExtension *pExtension)
Definition: upnpcds.cpp:186
bonjourregister.h
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:261
MediaServer::UnregisterExtension
void UnregisterExtension(UPnpCDSExtension *pExtension)
Definition: mediaserver.cpp:286
HtmlServerExtension
Definition: htmlserver.h:29
ServerPool::DefaultListen
static QList< QHostAddress > DefaultListen(void)
Definition: serverpool.cpp:305
htmlserver.h
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
MediaServer::Init
void Init(bool bIsMaster, bool bDisableUPnp=false)
Definition: mediaserver.cpp:54
UPnpCDSTv
Definition: upnpcdstv.h:20
MediaServer::MediaServer
MediaServer()
Definition: mediaserver.cpp:48
UPnpCMGR
Definition: upnpcmgr.h:48
UPnp::RootDevice
static UPnpDevice * RootDevice()
Definition: upnp.h:124
MediaServer::m_pUPnpCDS
UPnpCDS * m_pUPnpCDS
Definition: mediaserver.h:45
mediaserver.h
mythcorecontext.h
UPnpDeviceDesc::Load
bool Load(const QString &sFileName)
Definition: upnpdevice.cpp:42
internetContent.h
UPnpCDSVideo
Definition: upnpcdsvideo.h:23
HttpServer
Definition: httpserver.h:108
MediaServer::~MediaServer
~MediaServer() override
Definition: mediaserver.cpp:242
ServerPool::listen
bool listen(QList< QHostAddress > addrs, quint16 port, bool requireall=true, PoolServerType type=kTCPServer)
Definition: serverpool.cpp:395
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:845
UPnpCDSMusic
Definition: upnpcdsmusic.h:22
UPnp::m_pHttpServer
HttpServer * m_pHttpServer
Definition: upnp.h:102
upnpcdsmusic.h
WebSocketServer
The WebSocket server, which listens for connections.
Definition: websocket.h:38
MediaServer::m_webSocketServer
WebSocketServer * m_webSocketServer
Definition: mediaserver.h:41
UPnpCDS::RegisterExtension
void RegisterExtension(UPnpCDSExtension *pExtension)
Definition: upnpcds.cpp:167
UPnp::g_UPnpDeviceDesc
static UPnpDeviceDesc g_UPnpDeviceDesc
Definition: upnp.h:107
HttpConfig
Definition: httpconfig.h:11
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55