17#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
18#include <QStringConverter>
35 QTextStream &ts, std::chrono::microseconds ttLastNotified)
const
39 ts <<
"<?xml version=\"1.0\"?>" << Qt::endl
40 <<
"<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">" << Qt::endl;
42 for (
auto *prop : std::as_const(
m_map))
44 if ( ttLastNotified < prop->m_ttLastChanged )
48 ts <<
"<e:property>" << Qt::endl;
49 ts <<
"<" << prop->m_sName <<
">";
50 ts << prop->ToString();
51 ts <<
"</" << prop->m_sName <<
">";
52 ts <<
"</e:property>" << Qt::endl;
56 ts <<
"</e:propertyset>" << Qt::endl;
67 QString sEventMethodName,
68 const QString &sSharePath) :
70 m_sEventMethodName(
std::move(sEventMethodName)),
71 m_nSubscriptionDuration(
104 LOG(VB_GENERAL, LOG_ERR,
"Exceeded maximum guarranteed range of "
105 "m_nHoldCount short [-128..127]");
106 LOG(VB_GENERAL, LOG_ERR,
107 "UPnP may not exhibit strange behavior or crash mythtv");
140 return QStringList(
"/" );
157 LOG(VB_UPNP, LOG_INFO, QString(
"Eventing::ProcessRequest - Method (%1)")
213 if ( sCallBack.length() != 0 )
219 if ( sSID.length() != 0 )
225 if ( sNT !=
"upnp:event" )
234 sCallBack = sCallBack.mid( 1, sCallBack.indexOf(
">") - 1);
237 if ( sTimeout.startsWith(
"Second-") )
240 auto nValue = std::chrono::seconds(sTimeout.section(
"-", 1).toInt(&ok));
268 if ( sSID.length() != 0 )
270 sSID = sSID.mid( 5 );
276 if (pInfo !=
nullptr)
303 if ((sCallBack.length() != 0) || (sNT.length() != 0))
309 sSID = sSID.mid( 5 );
326 auto tt = nowAsDuration<std::chrono::microseconds>();
339 if (tt < (*it)->m_ttExpires)
362 if (pInfo ==
nullptr)
366 QTextStream tsBody( &aBody, QIODevice::WriteOnly );
368#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
369 tsBody.setCodec(QTextCodec::codecForName(
"UTF-8"));
371 tsBody.setEncoding(QStringConverter::Utf8);
384 auto *pBuffer =
new QByteArray();
385 QTextStream tsMsg( pBuffer, QIODevice::WriteOnly );
387#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
388 tsMsg.setCodec(QTextCodec::codecForName(
"UTF-8"));
390 tsMsg.setEncoding(QStringConverter::Utf8);
397 int nPort = (pInfo->
m_qURL.port()>=0) ? pInfo->
m_qURL.port() : 80;
398 QString sHost = QString(
"%1:%2" ).arg( pInfo->
m_qURL.host() )
401 tsMsg <<
"NOTIFY " << pInfo->
m_qURL.path() <<
" HTTP/1.1\r\n";
402 tsMsg <<
"HOST: " << sHost <<
"\r\n";
403 tsMsg <<
"CONTENT-TYPE: \"text/xml\"\r\n";
404 tsMsg <<
"Content-Length: " << QString::number( aBody.size() ) <<
"\r\n";
405 tsMsg <<
"NT: upnp:event\r\n";
406 tsMsg <<
"NTS: upnp:propchange\r\n";
407 tsMsg <<
"SID: uuid:" << pInfo->
m_sUUID <<
"\r\n";
408 tsMsg <<
"SEQ: " << QString::number( pInfo->
m_nKey ) <<
"\r\n";
417 LOG(VB_UPNP, LOG_INFO,
418 QString(
"UPnp::Eventing::NotifySubscriber( %1 ) : %2 Variables")
419 .arg( sHost ).arg(nCount));
426 pEventTask->DecrRef();
void HandleUnsubscribe(HTTPRequest *pRequest)
QString m_sEventMethodName
void HandleSubscribe(HTTPRequest *pRequest)
bool ProcessRequest(HTTPRequest *pRequest) override
void NotifySubscriber(SubscriberInfo *pInfo)
QStringList GetBasePaths() override
void ExecutePostProcess() override
Eventing(const QString &sExtensionName, QString sEventMethodName, const QString &sSharePath)
SubscriberInfo * m_pInitializeSubscriber
Subscribers m_subscribers
std::chrono::seconds m_nSubscriptionDuration
HttpResponseType m_eResponseType
QString GetRequestHeader(const QString &sKey, const QString &sDefault)
IPostProcess * m_pPostProcess
QStringMap m_mapRespHeaders
uint BuildNotifyBody(QTextStream &ts, std::chrono::microseconds ttLastNotified) const
std::chrono::microseconds m_ttLastNotified
unsigned long IncrementKey()
std::chrono::seconds m_nDuration
void AddTask(std::chrono::milliseconds msec, Task *pTask)
Add a task to run in the future.
static TaskQueue * Instance()
static void FormatErrorResponse(HTTPRequest *pRequest, UPnPResultCode eCode, const QString &sMsg="")
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
@ UPnPResult_InvalidAction