Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 845 lines (657 sloc) 27.434 kB
e677141 @dblain Initial uPnP Support.
dblain authored
1 //////////////////////////////////////////////////////////////////////////////
2 // Program Name: ssdp.cpp
4be4b25 @dblain Adds Copyright & GNU LGPLv3 to files.
dblain authored
3 // Created : Oct. 1, 2005
4 //
5 // Purpose : SSDP Discovery Service Implmenetation
e677141 @dblain Initial uPnP Support.
dblain authored
6 //
856b61b @dblain Framework API - Initial commit (Breaks MythXML support!)
dblain authored
7 // Copyright (c) 2005 David Blain <dblain@mythtv.org>
4be4b25 @dblain Adds Copyright & GNU LGPLv3 to files.
dblain authored
8 //
c1aadbb @dblain Changed Licensing to GPL v2 or later.
dblain authored
9 // Licensed under the GPL v2 or later, see COPYING for details
4be4b25 @dblain Adds Copyright & GNU LGPLv3 to files.
dblain authored
10 //
e677141 @dblain Initial uPnP Support.
dblain authored
11 //////////////////////////////////////////////////////////////////////////////
12
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
13 #include <algorithm>
14
e677141 @dblain Initial uPnP Support.
dblain authored
15 #include "upnp.h"
def93ad @Beirdo Added thread register/deregister to many missing spots
Beirdo authored
16 #include "mythlogging.h"
e677141 @dblain Initial uPnP Support.
dblain authored
17
18 #include "upnptasksearch.h"
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
19 #include "upnptaskcache.h"
20
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
21 #include "mmulticastsocketdevice.h"
22 #include "mbroadcastsocketdevice.h"
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
23
8f65209 @daniel-kristjansson Some more header cleanup.
daniel-kristjansson authored
24 #include <QRegExp>
25 #include <QStringList>
e677141 @dblain Initial uPnP Support.
dblain authored
26
4225b03 @jannau Closes #4165. Add missing includes for gcc-4.3 compilation. mostly cs…
jannau authored
27 #include <stdlib.h>
8882c75 @jyavenard Don’t treat EAGAIN or EWOULDBLOCK as error, instead retry up to 3 times
jyavenard authored
28 #include <errno.h>
e677141 @dblain Initial uPnP Support.
dblain authored
29
0cea0ad @stuartm Expand the Server variables to include more of RFC 3875
stuartm authored
30 using namespace std;
31
e677141 @dblain Initial uPnP Support.
dblain authored
32 /////////////////////////////////////////////////////////////////////////////
33 /////////////////////////////////////////////////////////////////////////////
34 //
35 // SSDP Class Implementation
36 //
37 /////////////////////////////////////////////////////////////////////////////
38 /////////////////////////////////////////////////////////////////////////////
39
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
40 // We're creating this class immediately so it will always be available.
41
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
42 static QMutex g_pSSDPCreationLock;
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
43 SSDP* SSDP::g_pSSDP = NULL;
44
e677141 @dblain Initial uPnP Support.
dblain authored
45 /////////////////////////////////////////////////////////////////////////////
46 //
47 /////////////////////////////////////////////////////////////////////////////
48
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
49 SSDP* SSDP::Instance()
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
50 {
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
51 QMutexLocker locker(&g_pSSDPCreationLock);
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
52 return g_pSSDP ? g_pSSDP : (g_pSSDP = new SSDP());
53 }
4a6dcb9 @daniel-kristjansson Refs #9993. Move SSDP and TaskQueue thread shutdown to mythcontext.
daniel-kristjansson authored
54
55 /////////////////////////////////////////////////////////////////////////////
56 //
57 /////////////////////////////////////////////////////////////////////////////
58
59 void SSDP::Shutdown()
60 {
61 QMutexLocker locker(&g_pSSDPCreationLock);
62 delete g_pSSDP;
63 g_pSSDP = NULL;
64 }
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
65
66 /////////////////////////////////////////////////////////////////////////////
67 //
68 /////////////////////////////////////////////////////////////////////////////
69
70 SSDP::SSDP() :
47d67e6 @daniel-kristjansson This adds two new classes MThread and MThreadPool to be used instead …
daniel-kristjansson authored
71 MThread ("SSDP" ),
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
72 m_procReqLineExp ("[ \r\n][ \r\n]*"),
73 m_nPort ( SSDP_PORT ),
74 m_nSearchPort ( SSDP_SEARCHPORT ),
75 m_nServicePort ( 0 ),
76 m_pNotifyTask ( NULL ),
77 m_bAnnouncementsEnabled( false ),
78 m_bTermRequested ( false ),
79 m_lock ( QMutex::NonRecursive )
80 {
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
81 LOG(VB_UPNP, LOG_NOTICE, "Starting up SSDP Thread..." );
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
82
83 Configuration *pConfig = UPnp::GetConfiguration();
84
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
85 m_nPort = pConfig->GetValue("UPnP/SSDP/Port" , SSDP_PORT );
86 m_nSearchPort = pConfig->GetValue("UPnP/SSDP/SearchPort", SSDP_SEARCHPORT);
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
87
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
88 m_Sockets[ SocketIdx_Search ] =
89 new MMulticastSocketDevice();
90 m_Sockets[ SocketIdx_Multicast ] =
91 new MMulticastSocketDevice(SSDP_GROUP, m_nPort);
92 m_Sockets[ SocketIdx_Broadcast ] =
93 new MBroadcastSocketDevice("255.255.255.255", m_nPort);
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
94
95 m_Sockets[ SocketIdx_Search ]->setBlocking( false );
96 m_Sockets[ SocketIdx_Multicast ]->setBlocking( false );
97 m_Sockets[ SocketIdx_Broadcast ]->setBlocking( false );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
98
99 // Setup SearchSocket
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
100 QHostAddress ip4addr( QHostAddress::Any );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
101
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
102 m_Sockets[ SocketIdx_Search ]->bind( ip4addr , m_nSearchPort );
b14a6cd @jannau merges qt4 branches back to trunk
jannau authored
103 m_Sockets[ SocketIdx_Search ]->bind( QHostAddress::Any, m_nSearchPort );
104
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
105 // ----------------------------------------------------------------------
106 // Create the SSDP (Upnp Discovery) Thread.
107 // ----------------------------------------------------------------------
108
109 start();
110
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
111 LOG(VB_UPNP, LOG_INFO, "SSDP Thread Starting soon" );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
112 }
113
114 /////////////////////////////////////////////////////////////////////////////
115 //
116 /////////////////////////////////////////////////////////////////////////////
117
118 SSDP::~SSDP()
e677141 @dblain Initial uPnP Support.
dblain authored
119 {
acb9402 @daniel-kristjansson Reduce some LOG_CRIT log level messages to LOG_NOTICE or LOG_ERR as a…
daniel-kristjansson authored
120 LOG(VB_UPNP, LOG_NOTICE, "Shutting Down SSDP Thread..." );
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
121
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
122 DisableNotifications();
123
1babd57 @NigelPearson Thread-safety fixes for UPnP destruction, thanks to Peter Stokes. Clo…
NigelPearson authored
124 m_bTermRequested = true;
125 wait();
126
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
127 if (m_pNotifyTask != NULL)
671017f @daniel-kristjansson Refs #10311. Port UPNP code from RefCounted to ReferenceCounter.
daniel-kristjansson authored
128 {
129 m_pNotifyTask->DecrRef();
130 m_pNotifyTask = NULL;
131 }
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
132
133 for (int nIdx = 0; nIdx < (int)NumberOfSockets; nIdx++ )
134 {
135 if (m_Sockets[ nIdx ] != NULL )
136 {
137 delete m_Sockets[ nIdx ];
138 }
139 }
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
140
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
141 LOG(VB_UPNP, LOG_INFO, "SSDP Thread Terminated." );
e677141 @dblain Initial uPnP Support.
dblain authored
142 }
143
f79cceb @daniel-kristjansson Implements SSDP::RequestTerminate()
daniel-kristjansson authored
144 void SSDP::RequestTerminate(void)
145 {
146 m_bTermRequested = true;
147 }
148
e677141 @dblain Initial uPnP Support.
dblain authored
149 /////////////////////////////////////////////////////////////////////////////
150 //
151 /////////////////////////////////////////////////////////////////////////////
152
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
153 void SSDP::EnableNotifications( int nServicePort )
e677141 @dblain Initial uPnP Support.
dblain authored
154 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
155 if ( m_pNotifyTask == NULL )
5569853 @dblain Merges the following patches:
dblain authored
156 {
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
157 m_nServicePort = nServicePort;
158
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
159 LOG(VB_UPNP, LOG_INFO,
160 "SSDP::EnableNotifications() - creating new task");
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
161 m_pNotifyTask = new UPnpNotifyTask( m_nServicePort );
e677141 @dblain Initial uPnP Support.
dblain authored
162
5569853 @dblain Merges the following patches:
dblain authored
163 // ------------------------------------------------------------------
164 // First Send out Notification that we are leaving the network.
165 // ------------------------------------------------------------------
166
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
167 LOG(VB_UPNP, LOG_INFO,
168 "SSDP::EnableNotifications() - sending NTS_byebye");
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
169 m_pNotifyTask->SetNTS( NTS_byebye );
170 m_pNotifyTask->Execute( NULL );
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
171
172 m_bAnnouncementsEnabled = true;
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
173 }
5569853 @dblain Merges the following patches:
dblain authored
174
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
175 // ------------------------------------------------------------------
176 // Add Announcement Task to the Queue
177 // ------------------------------------------------------------------
5569853 @dblain Merges the following patches:
dblain authored
178
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
179 LOG(VB_UPNP, LOG_INFO, "SSDP::EnableNotifications() - sending NTS_alive");
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
180
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
181 m_pNotifyTask->SetNTS( NTS_alive );
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
182
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
183 TaskQueue::Instance()->AddTask(m_pNotifyTask);
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
184
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
185 LOG(VB_UPNP, LOG_INFO,
186 "SSDP::EnableNotifications() - Task added to UPnP queue");
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
187 }
5569853 @dblain Merges the following patches:
dblain authored
188
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
189 /////////////////////////////////////////////////////////////////////////////
190 //
191 /////////////////////////////////////////////////////////////////////////////
192
193 void SSDP::DisableNotifications()
194 {
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
195 m_bAnnouncementsEnabled = false;
196
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
197 if (m_pNotifyTask != NULL)
198 {
199 // Send Announcement that we are leaving.
200
201 m_pNotifyTask->SetNTS( NTS_byebye );
202 m_pNotifyTask->Execute( NULL );
5569853 @dblain Merges the following patches:
dblain authored
203 }
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
204 }
205
206 /////////////////////////////////////////////////////////////////////////////
207 //
208 /////////////////////////////////////////////////////////////////////////////
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
209 void SSDP::PerformSearch(const QString &sST, uint timeout_secs)
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
210 {
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
211 timeout_secs = std::max(std::min(timeout_secs, 5U), 1U);
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
212 QString rRequest = QString("M-SEARCH * HTTP/1.1\r\n"
213 "HOST: 239.255.255.250:1900\r\n"
214 "MAN: \"ssdp:discover\"\r\n"
215 "MX: %1\r\n"
216 "ST: %2\r\n"
217 "\r\n")
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
218 .arg(timeout_secs).arg(sST);
219
c33d81c @Beirdo VERBOSE -> LOG in libmythtv, part 1
Beirdo authored
220 LOG(VB_UPNP, LOG_DEBUG, QString("\n\n%1\n").arg(rRequest));
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
221
a97c0d1 @daniel-kristjansson Refs #5311. Eliminates all ascii()/utf8()/latin1() calls & most Q3CSt…
daniel-kristjansson authored
222 QByteArray sRequest = rRequest.toUtf8();
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
223
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
224 MSocketDevice *pSocket = m_Sockets[ SocketIdx_Search ];
8bf5157 @GreyFoxx This patch adds IPv6 support to mythbackend and mythfrontend. I've be…
GreyFoxx authored
225 if ( !pSocket->isValid() )
226 {
227 pSocket->setProtocol(MSocketDevice::IPv4);
228 pSocket->setSocket(pSocket->createNewSocket(), MSocketDevice::Datagram);
229 }
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
230
231 QHostAddress address;
232 address.setAddress( SSDP_GROUP );
233
234 int nSize = sRequest.size();
235
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
236 if ( pSocket->writeBlock( sRequest.data(),
237 sRequest.size(), address, SSDP_PORT ) != nSize)
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
238 LOG(VB_GENERAL, LOG_INFO,
239 "SSDP::PerformSearch - did not write entire buffer.");
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
240
87a1746 @daniel-kristjansson Convert rand() usage to random().
daniel-kristjansson authored
241 usleep( random() % 250000 );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
242
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
243 if ( pSocket->writeBlock( sRequest.data(),
244 sRequest.size(), address, SSDP_PORT ) != nSize)
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
245 LOG(VB_GENERAL, LOG_INFO,
246 "SSDP::PerformSearch - did not write entire buffer.");
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
247 }
248
249 /////////////////////////////////////////////////////////////////////////////
250 //
251 /////////////////////////////////////////////////////////////////////////////
252
253 void SSDP::run()
254 {
47d67e6 @daniel-kristjansson This adds two new classes MThread and MThreadPool to be used instead …
daniel-kristjansson authored
255 RunProlog();
256
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
257 fd_set read_set;
258 struct timeval timeout;
e677141 @dblain Initial uPnP Support.
dblain authored
259
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
260 LOG(VB_UPNP, LOG_INFO, "SSDP::Run - SSDP Thread Started." );
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
261
e677141 @dblain Initial uPnP Support.
dblain authored
262 // ----------------------------------------------------------------------
5569853 @dblain Merges the following patches:
dblain authored
263 // Listen for new Requests
e677141 @dblain Initial uPnP Support.
dblain authored
264 // ----------------------------------------------------------------------
265
1babd57 @NigelPearson Thread-safety fixes for UPnP destruction, thanks to Peter Stokes. Clo…
NigelPearson authored
266 while ( ! m_bTermRequested )
e677141 @dblain Initial uPnP Support.
dblain authored
267 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
268 int nMaxSocket = 0;
e677141 @dblain Initial uPnP Support.
dblain authored
269
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
270 FD_ZERO( &read_set );
e677141 @dblain Initial uPnP Support.
dblain authored
271
4fca2a8 @daniel-kristjansson Don't segfault if socket failed to open in ssdp.cpp
daniel-kristjansson authored
272 for (uint nIdx = 0; nIdx < NumberOfSockets; nIdx++ )
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
273 {
4fca2a8 @daniel-kristjansson Don't segfault if socket failed to open in ssdp.cpp
daniel-kristjansson authored
274 if (m_Sockets[nIdx] != NULL && m_Sockets[nIdx]->socket() >= 0)
e677141 @dblain Initial uPnP Support.
dblain authored
275 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
276 FD_SET( m_Sockets[ nIdx ]->socket(), &read_set );
277 nMaxSocket = max( m_Sockets[ nIdx ]->socket(), nMaxSocket );
e677141 @dblain Initial uPnP Support.
dblain authored
278
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
279 #if 0
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
280 if (m_Sockets[ nIdx ]->bytesAvailable() > 0)
e677141 @dblain Initial uPnP Support.
dblain authored
281 {
d843c82 @daniel-kristjansson Tab cleanup.
daniel-kristjansson authored
282 LOG(VB_GENERAL, LOG_DEBUG,
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
283 QString("Found Extra data before select: %1")
d843c82 @daniel-kristjansson Tab cleanup.
daniel-kristjansson authored
284 .arg(nIdx));
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
285 ProcessData( m_Sockets[ nIdx ] );
e677141 @dblain Initial uPnP Support.
dblain authored
286 }
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
287 #endif
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
288 }
289 }
290
291 timeout.tv_sec = 1;
292 timeout.tv_usec = 0;
293
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
294 int count;
295 count = select(nMaxSocket + 1, &read_set, NULL, NULL, &timeout);
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
296
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
297 for (int nIdx = 0; count && nIdx < (int)NumberOfSockets; nIdx++ )
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
298 {
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
299 bool cond1 = m_Sockets[nIdx] != NULL;
300 bool cond2 = cond1 && m_Sockets[nIdx]->socket() >= 0;
301 bool cond3 = cond2 && FD_ISSET(m_Sockets[nIdx]->socket(), &read_set);
302
303 if (cond3)
d843c82 @daniel-kristjansson Tab cleanup.
daniel-kristjansson authored
304 {
8b9c0ba @Beirdo Change cout to logging where appropriate
Beirdo authored
305 #if 0
c33d81c @Beirdo VERBOSE -> LOG in libmythtv, part 1
Beirdo authored
306 LOG(VB_GENERAL, LOG_DEBUG, QString("FD_ISSET( %1 )").arg(nIdx));
8b9c0ba @Beirdo Change cout to logging where appropriate
Beirdo authored
307 #endif
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
308
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
309 ProcessData(m_Sockets[nIdx]);
310 count--;
e677141 @dblain Initial uPnP Support.
dblain authored
311 }
312 }
313 }
47d67e6 @daniel-kristjansson This adds two new classes MThread and MThreadPool to be used instead …
daniel-kristjansson authored
314
315 RunEpilog();
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
316 }
e677141 @dblain Initial uPnP Support.
dblain authored
317
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
318 /////////////////////////////////////////////////////////////////////////////
319 //
320 /////////////////////////////////////////////////////////////////////////////
321
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
322 void SSDP::ProcessData( MSocketDevice *pSocket )
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
323 {
44df943 @daniel-kristjansson Check for socket errors and handle partial reads in SSDP::ProcessData
daniel-kristjansson authored
324 QByteArray buffer;
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
325 long nBytes = pSocket->bytesAvailable();
8882c75 @jyavenard Don’t treat EAGAIN or EWOULDBLOCK as error, instead retry up to 3 times
jyavenard authored
326 int retries = 0;
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
327 // Note: this function MUST do a read even if someone sends a zero byte UDP message
328 // Otherwise the select() will continue to signal data ready, so to prevent using 100%
329 // CPU, we need to call a recv function to make select() block again
330 bool didDoRead = 0;
331
332 // UDP message of zero length? OK, "recv" it and move on
333 if (nBytes == 0)
334 {
335 LOG(VB_UPNP, LOG_WARNING, QString("SSDP: Received 0 byte UDP message"));
336 }
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
337
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
338 while ((nBytes = pSocket->bytesAvailable()) > 0 || (nBytes == 0 && !didDoRead))
5569853 @dblain Merges the following patches:
dblain authored
339 {
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
340 buffer.resize(nBytes);
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
341
44df943 @daniel-kristjansson Check for socket errors and handle partial reads in SSDP::ProcessData
daniel-kristjansson authored
342 long nRead = 0;
343 do
344 {
87e62f5 @jyavenard Fix crash.
jyavenard authored
345 long ret = pSocket->readBlock( buffer.data() + nRead, nBytes - nRead );
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
346 didDoRead = 1;
44df943 @daniel-kristjansson Check for socket errors and handle partial reads in SSDP::ProcessData
daniel-kristjansson authored
347 if (ret < 0)
348 {
8882c75 @jyavenard Don’t treat EAGAIN or EWOULDBLOCK as error, instead retry up to 3 times
jyavenard authored
349 if (errno == EAGAIN || errno == EWOULDBLOCK)
350 {
351 if (retries == 3)
352 {
353 nBytes = nRead;
354 buffer.resize(nBytes);
355 break;
356 }
357 retries++;
358 usleep(10000);
359 continue;
360 }
44df943 @daniel-kristjansson Check for socket errors and handle partial reads in SSDP::ProcessData
daniel-kristjansson authored
361 LOG(VB_GENERAL, LOG_ERR, QString("Socket readBlock error %1")
362 .arg(pSocket->error()));
363 buffer.clear();
364 break;
365 }
8882c75 @jyavenard Don’t treat EAGAIN or EWOULDBLOCK as error, instead retry up to 3 times
jyavenard authored
366 retries = 0;
44df943 @daniel-kristjansson Check for socket errors and handle partial reads in SSDP::ProcessData
daniel-kristjansson authored
367
368 nRead += ret;
369
4adfeff @warrenfalk fix SSDP thread using 100% CPU on zero byte datagrams
warrenfalk authored
370 if (0 == ret && nBytes != 0)
44df943 @daniel-kristjansson Check for socket errors and handle partial reads in SSDP::ProcessData
daniel-kristjansson authored
371 {
372 LOG(VB_SOCKET, LOG_WARNING,
373 QString("%1 bytes reported available, "
374 "but only %2 bytes read.")
375 .arg(nBytes).arg(nRead));
376 nBytes = nRead;
377 buffer.resize(nBytes);
378 break;
379 }
380 }
381 while (nRead < nBytes);
382
383 if (buffer.isEmpty())
384 continue;
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
385
3461b40 @stuartm SSDP: Missed changes when reverting [52cb0b5]
stuartm authored
386 QHostAddress peerAddress = pSocket->peerAddress();
387 quint16 peerPort = pSocket->peerPort ();
388
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
389 // ------------------------------------------------------------------
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
390 QString str = QString(buffer.constData());
391 QStringList lines = str.split("\r\n", QString::SkipEmptyParts);
392 QString sRequestLine = lines.size() ? lines[0] : "";
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
393
bb6e3a0 @stuartm Don't try to pop an entry from an empty list in SSDP::ProcessData. In…
stuartm authored
394 if (!lines.isEmpty())
395 lines.pop_front();
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
396
397 // ------------------------------------------------------------------
398 // Parse request Type
399 // ------------------------------------------------------------------
e677141 @dblain Initial uPnP Support.
dblain authored
400
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
401 LOG(VB_UPNP, LOG_DEBUG, QString("SSDP::ProcessData - requestLine: %1")
402 .arg(sRequestLine));
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
403
404 SSDPRequestType eType = ProcessRequestLine( sRequestLine );
405
406 // ------------------------------------------------------------------
407 // Read Headers into map
408 // ------------------------------------------------------------------
409
410 QStringMap headers;
411
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
412 for ( QStringList::Iterator it = lines.begin();
413 it != lines.end(); ++it )
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
414 {
415 QString sLine = *it;
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
416 QString sName = sLine.section( ':', 0, 0 ).trimmed();
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
417 QString sValue = sLine.section( ':', 1 );
418
419 sValue.truncate( sValue.length() ); //-2
420
421 if ((sName.length() != 0) && (sValue.length() !=0))
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
422 headers.insert( sName.toLower(), sValue.trimmed() );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
423 }
424
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
425 #if 0
426 pSocket->SetDestAddress( peerAddress, peerPort );
427 #endif
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
428
429 // --------------------------------------------------------------
430 // See if this is a valid request
431 // --------------------------------------------------------------
432
433 switch( eType )
434 {
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
435 case SSDP_MSearch:
436 {
437 // ----------------------------------------------------------
438 // If we haven't enabled notifications yet, then we don't
439 // want to answer search requests.
440 // ----------------------------------------------------------
441
442 if (m_pNotifyTask != NULL)
443 ProcessSearchRequest( headers, peerAddress, peerPort );
444
445 break;
446 }
447
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
448 case SSDP_MSearchResp:
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
449 ProcessSearchResponse( headers);
450 break;
451
452 case SSDP_Notify:
453 ProcessNotify( headers );
454 break;
455
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
456 case SSDP_Unknown:
457 default:
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
458 LOG(VB_UPNP, LOG_ERR,
459 "SSPD::ProcessData - Unknown request Type.");
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
460 break;
461 }
5569853 @dblain Merges the following patches:
dblain authored
462 }
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
463 }
464
465 /////////////////////////////////////////////////////////////////////////////
466 //
467 /////////////////////////////////////////////////////////////////////////////
468
469 SSDPRequestType SSDP::ProcessRequestLine( const QString &sLine )
470 {
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
471 QStringList tokens = sLine.split(m_procReqLineExp, QString::SkipEmptyParts);
e677141 @dblain Initial uPnP Support.
dblain authored
472
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
473 // ----------------------------------------------------------------------
474 // if this is actually a response, then sLine's format will be:
475 // HTTP/m.n <response code> <response text>
476 // otherwise:
477 // <method> <Resource URI> HTTP/m.n
478 // ----------------------------------------------------------------------
479
8acc7d5 @dblain Closes #6427 - libmythupnp QString efficiency work
dblain authored
480 if ( sLine.startsWith( QString("HTTP/") ))
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
481 return SSDP_MSearchResp;
482 else
5569853 @dblain Merges the following patches:
dblain authored
483 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
484 if (tokens.count() > 0)
485 {
486 if (tokens[0] == "M-SEARCH" ) return SSDP_MSearch;
487 if (tokens[0] == "NOTIFY" ) return SSDP_Notify;
488 }
5569853 @dblain Merges the following patches:
dblain authored
489 }
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
490
491 return SSDP_Unknown;
e677141 @dblain Initial uPnP Support.
dblain authored
492 }
493
494 /////////////////////////////////////////////////////////////////////////////
495 //
496 /////////////////////////////////////////////////////////////////////////////
497
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
498 QString SSDP::GetHeaderValue( const QStringMap &headers,
499 const QString &sKey, const QString &sDefault )
e677141 @dblain Initial uPnP Support.
dblain authored
500 {
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
501 QStringMap::const_iterator it = headers.find( sKey.toLower() );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
502
503 if ( it == headers.end())
504 return( sDefault );
505
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
506 return *it;
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
507 }
508
509 /////////////////////////////////////////////////////////////////////////////
510 //
511 /////////////////////////////////////////////////////////////////////////////
512
513 bool SSDP::ProcessSearchRequest( const QStringMap &sHeaders,
514 QHostAddress peerAddress,
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
515 quint16 peerPort )
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
516 {
517 QString sMAN = GetHeaderValue( sHeaders, "MAN", "" );
518 QString sST = GetHeaderValue( sHeaders, "ST" , "" );
519 QString sMX = GetHeaderValue( sHeaders, "MX" , "" );
e677141 @dblain Initial uPnP Support.
dblain authored
520 int nMX = 0;
521
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
522 LOG(VB_UPNP, LOG_DEBUG, QString("SSDP::ProcessSearchrequest : [%1] MX=%2")
523 .arg(sST).arg(sMX));
5569853 @dblain Merges the following patches:
dblain authored
524
e677141 @dblain Initial uPnP Support.
dblain authored
525 // ----------------------------------------------------------------------
526 // Validate Header Values...
527 // ----------------------------------------------------------------------
528
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
529 #if 0
530 if ( pRequest->m_sMethod != "*" ) return false;
531 if ( pRequest->m_sProtocol != "HTTP" ) return false;
532 if ( pRequest->m_nMajor != 1 ) return false;
533 #endif
e677141 @dblain Initial uPnP Support.
dblain authored
534 if ( sMAN != "\"ssdp:discover\"" ) return false;
535 if ( sST.length() == 0 ) return false;
536 if ( sMX.length() == 0 ) return false;
537 if ((nMX = sMX.toInt()) == 0 ) return false;
538 if ( nMX < 0 ) return false;
539
540 // ----------------------------------------------------------------------
541 // Adjust timeout to be a random interval between 0 and MX (max of 120)
542 // ----------------------------------------------------------------------
543
544 nMX = (nMX > 120) ? 120 : nMX;
545
87a1746 @daniel-kristjansson Convert rand() usage to random().
daniel-kristjansson authored
546 int nNewMX = (int)(0 + ((unsigned short)random() % nMX)) * 1000;
e677141 @dblain Initial uPnP Support.
dblain authored
547
548 // ----------------------------------------------------------------------
549 // See what they are looking for...
550 // ----------------------------------------------------------------------
551
552 if ((sST == "ssdp:all") || (sST == "upnp:rootdevice"))
553 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
554 UPnpSearchTask *pTask = new UPnpSearchTask( m_nServicePort,
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
555 peerAddress, peerPort, sST,
556 UPnp::g_UPnpDeviceDesc.m_rootDevice.GetUDN());
e677141 @dblain Initial uPnP Support.
dblain authored
557
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
558 #if 0
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
559 // Excute task now for fastest response, queue for time-delayed response
e677141 @dblain Initial uPnP Support.
dblain authored
560 // -=>TODO: To be trully uPnp compliant, this Execute should be removed.
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
561 pTask->Execute( NULL );
562 #endif
e677141 @dblain Initial uPnP Support.
dblain authored
563
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
564 TaskQueue::Instance()->AddTask( nNewMX, pTask );
e677141 @dblain Initial uPnP Support.
dblain authored
565
671017f @daniel-kristjansson Refs #10311. Port UPNP code from RefCounted to ReferenceCounter.
daniel-kristjansson authored
566 pTask->DecrRef();
567
e677141 @dblain Initial uPnP Support.
dblain authored
568 return true;
569 }
570
571 // ----------------------------------------------------------------------
572 // Look for a specific device/service
573 // ----------------------------------------------------------------------
574
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
575 QString sUDN = UPnp::g_UPnpDeviceDesc.FindDeviceUDN(
576 &(UPnp::g_UPnpDeviceDesc.m_rootDevice), sST );
e677141 @dblain Initial uPnP Support.
dblain authored
577
578 if (sUDN.length() > 0)
579 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
580 UPnpSearchTask *pTask = new UPnpSearchTask( m_nServicePort,
581 peerAddress,
e677141 @dblain Initial uPnP Support.
dblain authored
582 peerPort,
583 sST,
584 sUDN );
585
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
586 // Excute task now for fastest response, queue for time-delayed response
e677141 @dblain Initial uPnP Support.
dblain authored
587 // -=>TODO: To be trully uPnp compliant, this Execute should be removed.
588 pTask->Execute( NULL );
589
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
590 TaskQueue::Instance()->AddTask( nNewMX, pTask );
e677141 @dblain Initial uPnP Support.
dblain authored
591
671017f @daniel-kristjansson Refs #10311. Port UPNP code from RefCounted to ReferenceCounter.
daniel-kristjansson authored
592 pTask->DecrRef();
593
e677141 @dblain Initial uPnP Support.
dblain authored
594 return true;
595 }
596
597 return false;
598 }
599
600 /////////////////////////////////////////////////////////////////////////////
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
601 //
602 /////////////////////////////////////////////////////////////////////////////
603
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
604 bool SSDP::ProcessSearchResponse( const QStringMap &headers )
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
605 {
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
606 QString sDescURL = GetHeaderValue( headers, "LOCATION" , "" );
607 QString sST = GetHeaderValue( headers, "ST" , "" );
608 QString sUSN = GetHeaderValue( headers, "USN" , "" );
609 QString sCache = GetHeaderValue( headers, "CACHE-CONTROL" , "" );
610
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
611 LOG(VB_UPNP, LOG_DEBUG,
612 QString( "SSDP::ProcessSearchResponse ...\n"
613 "DescURL=%1\n"
614 "ST =%2\n"
615 "USN =%3\n"
616 "Cache =%4")
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
617 .arg(sDescURL).arg(sST).arg(sUSN).arg(sCache));
1e890c8 @dblain Resolved various uPnP issues with Videos.
dblain authored
618
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
619 int nPos = sCache.indexOf("max-age", 0, Qt::CaseInsensitive);
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
620
621 if (nPos < 0)
622 return false;
623
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
624 if ((nPos = sCache.indexOf("=", nPos)) < 0)
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
625 return false;
626
627 int nSecs = sCache.mid( nPos+1 ).toInt();
628
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
629 SSDPCache::Instance()->Add( sST, sUSN, sDescURL, nSecs );
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
630
631 return true;
632 }
633
634 /////////////////////////////////////////////////////////////////////////////
635 //
636 /////////////////////////////////////////////////////////////////////////////
637
638 bool SSDP::ProcessNotify( const QStringMap &headers )
639 {
640 QString sDescURL = GetHeaderValue( headers, "LOCATION" , "" );
641 QString sNTS = GetHeaderValue( headers, "NTS" , "" );
642 QString sNT = GetHeaderValue( headers, "NT" , "" );
643 QString sUSN = GetHeaderValue( headers, "USN" , "" );
644 QString sCache = GetHeaderValue( headers, "CACHE-CONTROL" , "" );
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
645
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
646 LOG(VB_UPNP, LOG_DEBUG,
647 QString( "SSDP::ProcessNotify ...\n"
648 "DescURL=%1\n"
649 "NTS =%2\n"
650 "NT =%3\n"
651 "USN =%4\n"
652 "Cache =%5" )
653 .arg(sDescURL).arg(sNTS).arg(sNT).arg(sUSN).arg(sCache));
1e890c8 @dblain Resolved various uPnP issues with Videos.
dblain authored
654
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
655 if (sNTS.contains( "ssdp:alive"))
656 {
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
657 int nPos = sCache.indexOf("max-age", 0, Qt::CaseInsensitive);
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
658
659 if (nPos < 0)
660 return false;
661
e4545ec @daniel-kristjansson Fixes #5592. Qt4'ifies libmythupnp.
daniel-kristjansson authored
662 if ((nPos = sCache.indexOf("=", nPos)) < 0)
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
663 return false;
664
665 int nSecs = sCache.mid( nPos+1 ).toInt();
666
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
667 SSDPCache::Instance()->Add( sNT, sUSN, sDescURL, nSecs );
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
668
669 return true;
670 }
671
672
673 if ( sNTS.contains( "ssdp:byebye" ) )
674 {
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
675 SSDPCache::Instance()->Remove( sNT, sUSN );
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
676
677 return true;
678 }
679
680 return false;
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
681 }
682
683 /////////////////////////////////////////////////////////////////////////////
e677141 @dblain Initial uPnP Support.
dblain authored
684 /////////////////////////////////////////////////////////////////////////////
685 //
b7700a7 @jannau fix spelling mistakes. Fixes %5782
jannau authored
686 // SSDPExtension Implementation
e677141 @dblain Initial uPnP Support.
dblain authored
687 //
688 /////////////////////////////////////////////////////////////////////////////
689 /////////////////////////////////////////////////////////////////////////////
690
691 /////////////////////////////////////////////////////////////////////////////
692 //
693 /////////////////////////////////////////////////////////////////////////////
694
682b1cb @dekarl LibMythupnp: pass const QStrings by reference (cppcheck)
dekarl authored
695 SSDPExtension::SSDPExtension( int nServicePort , const QString &sSharePath)
5057e8a Tidy up some UPNP inheritance and initialisation. The shared path was…
Mark Kendall authored
696 : HttpServerExtension( "SSDP" , sSharePath),
697 m_nServicePort(nServicePort)
e677141 @dblain Initial uPnP Support.
dblain authored
698 {
373e52c @stuartm HTTP: Add partial handling of OPTIONS and framework for 405 errors
stuartm authored
699 m_nSupportedMethods |= (RequestTypeMSearch | RequestTypeNotify);
18be98c @dblain Fixes seg fault when starting up mythbackend when there is no mysql.t…
dblain authored
700 m_sUPnpDescPath = UPnp::GetConfiguration()->GetValue( "UPnP/DescXmlPath",
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
701 m_sSharePath );
e677141 @dblain Initial uPnP Support.
dblain authored
702 }
703
704 /////////////////////////////////////////////////////////////////////////////
705 //
706 /////////////////////////////////////////////////////////////////////////////
707
708 SSDPExtension::~SSDPExtension( )
709 {
710 }
711
712 /////////////////////////////////////////////////////////////////////////////
713 //
714 /////////////////////////////////////////////////////////////////////////////
715
716 SSDPMethod SSDPExtension::GetMethod( const QString &sURI )
717 {
c51d3e2 @dblain Initial support for auto discovery of MythTv Servers/Frontends.
dblain authored
718 if (sURI == "getDeviceDesc" ) return( SSDPM_GetDeviceDesc );
1ba4eba @dblain Added temporary method 'getDeviceList' to return the current upnp dev…
dblain authored
719 if (sURI == "getDeviceList" ) return( SSDPM_GetDeviceList );
e677141 @dblain Initial uPnP Support.
dblain authored
720
721 return( SSDPM_Unknown );
722 }
723
724 /////////////////////////////////////////////////////////////////////////////
725 //
726 /////////////////////////////////////////////////////////////////////////////
727
5a77467 @dblain Optimize the delegation to HttpServerExtensions. Also fixed bug in S…
dblain authored
728 QStringList SSDPExtension::GetBasePaths()
729 {
730 // -=>TODO: This is very inefficient... should look into making
731 // it a unique path.
732
733 return QStringList( "/" );
734 }
735
736 /////////////////////////////////////////////////////////////////////////////
737 //
738 /////////////////////////////////////////////////////////////////////////////
739
37961e2 @daniel-kristjansson Convert UPnP to MThreadPool
daniel-kristjansson authored
740 bool SSDPExtension::ProcessRequest( HTTPRequest *pRequest )
e677141 @dblain Initial uPnP Support.
dblain authored
741 {
742 if (pRequest)
743 {
744 if ( pRequest->m_sBaseUrl != "/")
745 return( false );
746
747 switch( GetMethod( pRequest->m_sMethod ))
748 {
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
749 case SSDPM_GetDeviceDesc: GetDeviceDesc( pRequest ); return( true );
750 case SSDPM_GetDeviceList: GetDeviceList( pRequest ); return( true );
190060f @GreyFoxx This adds a new X_MS_MediaReceiverRegistrar upnp service for MS DRM …
GreyFoxx authored
751
5fb8bf1 - Minor warnings fixes for new upnp lib.
Isaac Richards authored
752 default: break;
e677141 @dblain Initial uPnP Support.
dblain authored
753 }
754 }
755
756 return( false );
757 }
758
759 /////////////////////////////////////////////////////////////////////////////
760 //
761 /////////////////////////////////////////////////////////////////////////////
762
763 void SSDPExtension::GetDeviceDesc( HTTPRequest *pRequest )
764 {
765 pRequest->m_eResponseType = ResponseTypeXML;
766
22736f9 @stuartm WebFrontend: Add a restrictive Content-Security-Policy header
stuartm authored
767 QString sUserAgent = pRequest->GetRequestHeader( "User-Agent", "" );
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
768
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
769 LOG(VB_UPNP, LOG_DEBUG, "SSDPExtension::GetDeviceDesc - " +
770 QString( "Host=%1 Port=%2 UserAgent=%3" )
771 .arg(pRequest->GetHostAddress()) .arg(m_nServicePort)
772 .arg(sUserAgent));
1e890c8 @dblain Resolved various uPnP issues with Videos.
dblain authored
773
856b61b @dblain Framework API - Initial commit (Breaks MythXML support!)
dblain authored
774 QTextStream stream( &(pRequest->m_response) );
1e890c8 @dblain Resolved various uPnP issues with Videos.
dblain authored
775
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
776 UPnp::g_UPnpDeviceDesc.GetValidXML( pRequest->GetHostAddress(),
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
777 m_nServicePort,
856b61b @dblain Framework API - Initial commit (Breaks MythXML support!)
dblain authored
778 stream,
526cf69 @dblain Fixed issue with socket not blocking when writing out response.
dblain authored
779 sUserAgent );
e677141 @dblain Initial uPnP Support.
dblain authored
780 }
781
782 /////////////////////////////////////////////////////////////////////////////
783 //
784 /////////////////////////////////////////////////////////////////////////////
785
786 void SSDPExtension::GetFile( HTTPRequest *pRequest, QString sFileName )
787 {
788 pRequest->m_eResponseType = ResponseTypeHTML;
789
790 pRequest->m_sFileName = m_sUPnpDescPath + sFileName;
791
792 if (QFile::exists( pRequest->m_sFileName ))
793 {
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
794 LOG(VB_UPNP, LOG_DEBUG,
795 QString("SSDPExtension::GetFile( %1 ) - Exists")
796 .arg(pRequest->m_sFileName));
e677141 @dblain Initial uPnP Support.
dblain authored
797
391db79 @NigelPearson Make -v upnp less verbose (moved some messages to -v upnp,extra),
NigelPearson authored
798 pRequest->m_eResponseType = ResponseTypeFile;
799 pRequest->m_nResponseStatus = 200;
800 pRequest->m_mapRespHeaders[ "Cache-Control" ]
9706d36 @stuartm HTTP: Add support for If-Modified-Since request header
stuartm authored
801 = "no-cache=\"Ext\", max-age = 7200"; // 2 hours
e677141 @dblain Initial uPnP Support.
dblain authored
802 }
1e890c8 @dblain Resolved various uPnP issues with Videos.
dblain authored
803 else
804 {
9706d36 @stuartm HTTP: Add support for If-Modified-Since request header
stuartm authored
805 pRequest->m_nResponseStatus = 404;
806 pRequest->m_response.write( pRequest->GetResponsePage() );
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
807 LOG(VB_UPNP, LOG_ERR,
808 QString("SSDPExtension::GetFile( %1 ) - Not Found")
809 .arg(pRequest->m_sFileName));
1e890c8 @dblain Resolved various uPnP issues with Videos.
dblain authored
810 }
e677141 @dblain Initial uPnP Support.
dblain authored
811
812 }
1ba4eba @dblain Added temporary method 'getDeviceList' to return the current upnp dev…
dblain authored
813
814 /////////////////////////////////////////////////////////////////////////////
85bb976 @dblain Extensive changes were made to the UPnP stack in order to organize it…
dblain authored
815 //
1ba4eba @dblain Added temporary method 'getDeviceList' to return the current upnp dev…
dblain authored
816 /////////////////////////////////////////////////////////////////////////////
817
818 void SSDPExtension::GetDeviceList( HTTPRequest *pRequest )
819 {
5502c52 @Beirdo Convert VERBOSE -> LOG in libmythupnp
Beirdo authored
820 LOG(VB_UPNP, LOG_DEBUG, "SSDPExtension::GetDeviceList");
957f2ef @daniel-kristjansson This ports a few UPnP changes over from mythtv-rec2.
daniel-kristjansson authored
821
822 QString sXML;
823 QTextStream os(&sXML, QIODevice::WriteOnly);
824
825 uint nDevCount, nEntryCount;
826 SSDPCache::Instance()->OutputXML(os, &nDevCount, &nEntryCount);
827
828 NameValues list;
829 list.push_back(
830 NameValue("DeviceCount", (int)nDevCount));
831 list.push_back(
832 NameValue("DevicesAllocated", SSDPCacheEntries::g_nAllocated));
833 list.push_back(
834 NameValue("CacheEntriesFound", (int)nEntryCount));
835 list.push_back(
836 NameValue("CacheEntriesAllocated", DeviceLocation::g_nAllocated));
837 list.push_back(
838 NameValue("DeviceList", sXML));
839
840 pRequest->FormatActionResponse(list);
1ba4eba @dblain Added temporary method 'getDeviceList' to return the current upnp dev…
dblain authored
841
842 pRequest->m_eResponseType = ResponseTypeXML;
843 pRequest->m_nResponseStatus = 200;
844 }
Something went wrong with that request. Please try again.