22 #define SUBSCRIPTION_TIME 1800
24 #define MAX_WAIT 30000
26 #define LOC QString("UPnPSub: ")
49 if (addr.protocol() == QAbstractSocket::IPv6Protocol)
50 host =
"[" + addr.toString() +
"]";
52 host = addr.toString();
54 m_callback = QString(
"http://%1:%2/Subscriptions/event?usn=")
55 .arg(host).arg(QString::number(port));
62 while (!usns.isEmpty())
67 LOG(VB_UPNP, LOG_DEBUG,
LOC +
"Finished");
73 LOG(VB_UPNP, LOG_DEBUG,
LOC + QString(
"Subscribe %1 %2 %3")
74 .
arg(usn).
arg(url.toString()).arg(path));
87 LOG(VB_GENERAL, LOG_WARNING,
LOC +
88 "Re-subscribing with different url and path.");
107 QString uuid = QString();
125 LOG(VB_UPNP, LOG_DEBUG,
LOC + QString(
"Renew: %1").
arg(usn));
141 LOG(VB_UPNP, LOG_ERR,
LOC + QString(
"Unrecognised renewal usn: %1")
152 LOG(VB_UPNP, LOG_ERR,
LOC + QString(
"No uuid - not renewing usn: %1")
166 LOG(VB_UPNP, LOG_INFO,
LOC + QString(
"Removing %1").
arg(usn));
183 LOG(VB_UPNP, LOG_DEBUG,
LOC + QString(
"%1\n%2")
195 if (nt.isEmpty() || nts.isEmpty() || !no)
202 if (nt !=
"upnp:event" || nts !=
"upnp:propchange")
207 if (usn.isEmpty() || sid.isEmpty())
220 int loc = pRequest->
m_sPayload.lastIndexOf(
"propertyset>");
221 QString payload = (loc > -1) ? pRequest->
m_sPayload.left(loc + 12) :
224 LOG(VB_UPNP, LOG_DEBUG,
LOC + QString(
"Payload:\n%1").
arg(payload));
231 if (!body.setContent(payload,
true, &
error, &errorLine, &errorCol))
233 LOG(VB_GENERAL, LOG_ERR,
LOC +
234 QString(
"Failed to parse event: Line: %1 Col: %2 Error: '%3'")
239 LOG(VB_UPNP, LOG_DEBUG,
LOC +
"/n/n" + body.toString(4) +
"/n/n");
241 QDomNodeList properties = body.elementsByTagName(
"property");
246 for (
int i = 0; i < properties.size(); i++)
248 QDomNodeList arguments = properties.at(i).childNodes();
249 for (
int j = 0; j < arguments.size(); j++)
251 QDomElement
e = arguments.at(j).toElement();
252 if (!
e.isNull() && !
e.text().isEmpty() && !
e.tagName().isEmpty())
277 bool success =
false;
278 QString host = url.host();
279 int port = url.port();
282 QTextStream data(&sub);
283 data.setCodec(QTextCodec::codecForName(
"UTF-8"));
285 data << QString(
"UNSUBSCRIBE %1 HTTP/1.1\r\n").arg(path);
286 data << QString(
"HOST: %1:%2\r\n").arg(host).arg(QString::number(port));
287 data << QString(
"SID: uuid:%1\r\n").arg(uuid);
291 LOG(VB_UPNP, LOG_DEBUG,
LOC +
"\n\n" + sub);
293 auto *sockdev =
new MSocketDevice(MSocketDevice::Stream);
295 sockdev->setBlocking(
true);
297 if (sock->Connect(QHostAddress(host), port))
299 if (sock->WriteBlockDirect(sub.constData(), sub.size()) != -1)
301 QString line = sock->ReadLine(
MAX_WAIT);
302 success = !line.isEmpty();
306 LOG(VB_GENERAL, LOG_ERR,
LOC +
307 QString(
"Socket write error for %1:%2") .
arg(host).
arg(port));
313 LOG(VB_GENERAL, LOG_ERR,
LOC +
314 QString(
"Failed to open socket for %1:%2") .
arg(host).
arg(port));
320 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Unsubscribed to %1").
arg(usn));
322 LOG(VB_UPNP, LOG_WARNING,
LOC + QString(
"Failed to unsubscribe to %1")
331 const QString &uuidin,
334 QString host = url.host();
335 int port = url.port();
338 QTextStream data(&sub);
339 data.setCodec(QTextCodec::codecForName(
"UTF-8"));
341 data << QString(
"SUBSCRIBE %1 HTTP/1.1\r\n").arg(path);
342 data << QString(
"HOST: %1:%2\r\n").arg(host).arg(QString::number(port));
345 if (uuidin.isEmpty())
347 data << QString(
"CALLBACK: <%1%2>\r\n")
348 .arg(callback).arg(usn);
349 data <<
"NT: upnp:event\r\n";
352 data << QString(
"SID: uuid:%1\r\n").arg(uuidin);
358 LOG(VB_UPNP, LOG_DEBUG,
LOC +
"\n\n" + sub);
360 auto *sockdev =
new MSocketDevice(MSocketDevice::Stream);
362 sockdev->setBlocking(
true);
368 if (sock->Connect(QHostAddress(host), port))
370 if (sock->WriteBlockDirect(sub.constData(), sub.size()) != -1)
373 QString line = sock->ReadLine(
MAX_WAIT);
374 while (!line.isEmpty())
376 LOG(VB_UPNP, LOG_DEBUG,
LOC + line);
377 if (line.contains(
"HTTP/1.1 200 OK", Qt::CaseInsensitive))
379 if (line.startsWith(
"SID:", Qt::CaseInsensitive))
380 uuid = line.mid(4).trimmed().mid(5).trimmed();
381 if (line.startsWith(
"TIMEOUT:", Qt::CaseInsensitive))
382 timeout = line.mid(8).trimmed().mid(7).trimmed();
383 if (ok && !uuid.isEmpty() && !
timeout.isEmpty())
388 if (ok && !uuid.isEmpty() && !
timeout.isEmpty())
395 LOG(VB_GENERAL, LOG_ERR,
LOC +
396 QString(
"Failed to subscribe to %1").
arg(usn));
401 LOG(VB_GENERAL, LOG_ERR,
LOC +
402 QString(
"Socket write error for %1:%2") .
arg(host).
arg(port));
408 LOG(VB_GENERAL, LOG_ERR,
LOC +
409 QString(
"Failed to open socket for %1:%2") .
arg(host).
arg(port));