Skip to content

Commit

Permalink
MythUDPListener: Start cleanup
Browse files Browse the repository at this point in the history
- round 1 of sundry cleanup before bigger change to move it out of the
main thread
  • Loading branch information
mark-kendall committed Jan 2, 2021
1 parent 90822cb commit 50cb7c0
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 102 deletions.
2 changes: 2 additions & 0 deletions mythtv/libs/libmythui/mythmainwindow.cpp
Expand Up @@ -212,6 +212,8 @@ MythMainWindow::~MythMainWindow()
if (gCoreContext != nullptr)
gCoreContext->removeListener(this);

delete m_priv->m_udpListener;

while (!m_priv->m_stackList.isEmpty())
{
MythScreenStack *stack = m_priv->m_stackList.back();
Expand Down
146 changes: 63 additions & 83 deletions mythtv/libs/libmythui/mythudplistener.cpp
@@ -1,9 +1,9 @@
// Qt
#include <QCoreApplication>
#include <QUdpSocket>
#include <QDomDocument>
#include <QList>
#include <QHostAddress>

// MythTV
#include "mythcorecontext.h"
#include "mythlogging.h"
#include "mythmainwindow.h"
Expand All @@ -16,169 +16,149 @@ MythUDPListener::MythUDPListener()
Enable();
}

void MythUDPListener::deleteLater(void)
MythUDPListener::~MythUDPListener()
{
Disable();
disconnect();
QObject::deleteLater();
}

void MythUDPListener::Enable(void)
void MythUDPListener::Enable()
{
if (m_socketPool)
return;

LOG(VB_GENERAL, LOG_INFO, LOC + "Enabling");

m_socketPool = new ServerPool(this);
connect(m_socketPool, &ServerPool::newDatagram,
this, &MythUDPListener::Process);

connect(m_socketPool, &ServerPool::newDatagram, this, &MythUDPListener::Process);
QList<QHostAddress> addrs = ServerPool::DefaultListen();
addrs << ServerPool::DefaultBroadcast();

if (!m_socketPool->bind(addrs,
gCoreContext->GetNumSetting("UDPNotifyPort", 0), false))
auto port = static_cast<uint16_t>(gCoreContext->GetNumSetting("UDPNotifyPort", 0));
if (!m_socketPool->bind(addrs, port, false))
{
delete m_socketPool;
m_socketPool = nullptr;
}
}

void MythUDPListener::Disable(void)
void MythUDPListener::Disable()
{
if (!m_socketPool)
return;

LOG(VB_GENERAL, LOG_INFO, LOC + "Disabling");

m_socketPool->close();
delete m_socketPool;
m_socketPool = nullptr;
}

void MythUDPListener::Process(const QByteArray &buf, const QHostAddress& /*sender*/,
quint16 /*senderPort*/)
void MythUDPListener::Process(const QByteArray& Buffer, const QHostAddress& /*Sender*/,
quint16 /*SenderPort*/)
{
QString errorMsg;
int errorLine = 0;
int errorColumn = 0;
QString msg;
int line = 0;
int column = 0;
QDomDocument doc;
if (!doc.setContent(buf, false, &errorMsg, &errorLine, &errorColumn))
if (!doc.setContent(Buffer, false, &msg, &line, &column))
{
LOG(VB_GENERAL, LOG_ERR, LOC +
QString("Parsing xml:\n\t\t\t at line: %1 column: %2\n\t\t\t%3")
.arg(errorLine).arg(errorColumn).arg(errorMsg));

LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error parsing xml: Line: %1 Column: %2 Error: %3")
.arg(line).arg(column).arg(msg));
return;
}

QDomElement docElem = doc.documentElement();
auto element = doc.documentElement();
bool notification = false;
if (!docElem.isNull())
if (!element.isNull())
{
if (docElem.tagName() != "mythmessage" &&
docElem.tagName() != "mythnotification")
if (element.tagName() != "mythmessage" && element.tagName() != "mythnotification")
{
LOG(VB_GENERAL, LOG_ERR, LOC +
"Unknown UDP packet (not <mythmessage> XML)");
LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown UDP packet (not <mythmessage> XML)");
return;
}

if (docElem.tagName() == "mythnotification")
{
if (element.tagName() == "mythnotification")
notification = true;
}

QString version = docElem.attribute("version", "");
if (version.isEmpty())
if (auto version = element.attribute("version", ""); version.isEmpty())
{
LOG(VB_GENERAL, LOG_ERR, LOC +
"<mythmessage> missing 'version' attribute");
LOG(VB_GENERAL, LOG_ERR, LOC + "<mythmessage> missing 'version' attribute");
return;
}
}

QString msg = QString("");
uint timeout = 0;
QString image;
QString origin;
QString description = "";
QString extra = "";
QString progress_text = "";
QString description;
QString extra;
QString progress_text;
float progress = -1.0F;
bool fullscreen = false;
bool error = false;
int visibility = 0;
QString type = "normal";

QDomNode n = docElem.firstChild();
while (!n.isNull())
auto node = element.firstChild();
while (!node.isNull())
{
QDomElement e = n.toElement();
if (!e.isNull())
auto dom = node.toElement();
if (!dom.isNull())
{
if (e.tagName() == "text")
msg = e.text();
else if (e.tagName() == "timeout")
timeout = e.text().toUInt();
else if (notification && e.tagName() == "image")
image = e.text();
else if (notification && e.tagName() == "origin")
origin = e.text();
else if (notification && e.tagName() == "description")
description = e.text();
else if (notification && e.tagName() == "extra")
extra = e.text();
else if (notification && e.tagName() == "progress_text")
progress_text = e.text();
else if (notification && e.tagName() == "fullscreen")
fullscreen = e.text().toLower() == "true";
else if (notification && e.tagName() == "error")
error = e.text().toLower() == "true";
else if (e.tagName() == "visibility")
visibility = e.text().toUInt();
else if (e.tagName() == "type")
type = e.text();
else if (notification && e.tagName() == "progress")
auto tagname = dom.tagName();
if (tagname == "text")
msg = dom.text();
else if (tagname == "timeout")
timeout = dom.text().toUInt();
else if (notification && tagname == "image")
image = dom.text();
else if (notification && tagname == "origin")
origin = dom.text();
else if (notification && tagname == "description")
description = dom.text();
else if (notification && tagname == "extra")
extra = dom.text();
else if (notification && tagname == "progress_text")
progress_text = dom.text();
else if (notification && tagname == "fullscreen")
fullscreen = dom.text().toLower() == "true";
else if (notification && tagname == "error")
msg = dom.text().toLower() == "true";
else if (tagname == "visibility")
visibility = dom.text().toInt();
else if (tagname == "type")
type = dom.text();
else if (notification && tagname == "progress")
{
bool ok = false;
progress = e.text().toFloat(&ok);
if (!ok)
if (progress = dom.text().toFloat(&ok); !ok)
progress = -1.0F;
}
else
{
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unknown element: %1")
.arg(e.tagName()));
.arg(tagname));
}
}
n = n.nextSibling();
node = node.nextSibling();
}

if (!msg.isEmpty() || !image.isEmpty() || !extra.isEmpty())
{
LOG(VB_GENERAL, LOG_INFO, QString("Received %1 '%2', timeout %3")
.arg(notification ? "notification" : "message")
.arg(msg).arg(timeout));
.arg(notification ? "notification" : "message").arg(msg).arg(timeout));
if (timeout > 1000)
timeout = notification ? 5 : 0;
if (notification)
{
origin = origin.isNull() ? tr("UDP Listener") : origin;
origin = origin.isEmpty() ? tr("UDP Listener") : origin;
ShowNotification(error ? MythNotification::Error :
MythNotification::TypeFromString(type),
msg, origin, description, image, extra,
progress_text, progress, timeout, fullscreen,
visibility);
progress_text, progress, static_cast<int>(timeout),
fullscreen, static_cast<VNMask>(visibility));
}
else
{
QStringList args;
args << QString::number(timeout);
MythMainWindow *window = GetMythMainWindow();
auto* me = new MythEvent(MythEvent::MythUserMessage, msg, args);
qApp->postEvent(window, me);
QStringList args(QString::number(timeout));
qApp->postEvent(GetMythMainWindow(), new MythEvent(MythEvent::MythUserMessage, msg, args));
}
}
}
27 changes: 8 additions & 19 deletions mythtv/libs/libmythui/mythudplistener.h
@@ -1,38 +1,27 @@
#ifndef MYTHUDPLISTENER_H
#define MYTHUDPLISTENER_H

// Qt
#include <QObject>

// MythTV
#include "serverpool.h"

class QByteArray;
class QUdpSocket;
class QDomElement;

class MythUDPListener : public QObject
{
Q_OBJECT

public:
MythUDPListener();

void Enable(void);
void Disable(void);

public slots:
virtual void deleteLater(void);
~MythUDPListener() override;
void Enable();
void Disable();

private slots:
static void Process(const QByteArray &buf, const QHostAddress& sender,
quint16 senderPort);

private:
~MythUDPListener(void) override { Disable(); }

void TeardownAll(void) { Disable(); }
static void Process(const QByteArray &Buffer, const QHostAddress& /*Sender*/, quint16 /*SenderPort*/);

private:
ServerPool *m_socketPool {nullptr};
ServerPool* m_socketPool { nullptr };
};

#endif // MYTHUDPLISTENER_H
#endif

0 comments on commit 50cb7c0

Please sign in to comment.