MythTV  master
mythudplistener.cpp
Go to the documentation of this file.
1 #include <QCoreApplication>
2 #include <QUdpSocket>
3 #include <QDomDocument>
4 #include <QList>
5 #include <QHostAddress>
6 
7 #include "mythcorecontext.h"
8 #include "mythlogging.h"
9 #include "mythmainwindow.h"
10 #include "mythudplistener.h"
11 
12 #define LOC QString("UDPListener: ")
13 
15 {
16  Enable();
17 }
18 
20 {
21  Disable();
22  disconnect();
23  QObject::deleteLater();
24 }
25 
27 {
28  if (m_socketPool)
29  return;
30 
31  LOG(VB_GENERAL, LOG_INFO, LOC + "Enabling");
32 
33  m_socketPool = new ServerPool(this);
34  connect(m_socketPool, SIGNAL(newDatagram(QByteArray, QHostAddress,
35  quint16)),
36  this, SLOT(Process(const QByteArray, QHostAddress,
37  quint16)));
38 
39  QList<QHostAddress> addrs = ServerPool::DefaultListen();
41 
42  if (!m_socketPool->bind(addrs,
43  gCoreContext->GetNumSetting("UDPNotifyPort", 0), false))
44  {
45  delete m_socketPool;
46  m_socketPool = nullptr;
47  }
48 }
49 
51 {
52  if (!m_socketPool)
53  return;
54 
55  LOG(VB_GENERAL, LOG_INFO, LOC + "Disabling");
56 
58  delete m_socketPool;
59  m_socketPool = nullptr;
60 }
61 
62 void MythUDPListener::Process(const QByteArray &buf, const QHostAddress& /*sender*/,
63  quint16 /*senderPort*/)
64 {
65  QString errorMsg;
66  int errorLine = 0;
67  int errorColumn = 0;
68  QDomDocument doc;
69  if (!doc.setContent(buf, false, &errorMsg, &errorLine, &errorColumn))
70  {
71  LOG(VB_GENERAL, LOG_ERR, LOC +
72  QString("Parsing xml:\n\t\t\t at line: %1 column: %2\n\t\t\t%3")
73  .arg(errorLine).arg(errorColumn).arg(errorMsg));
74 
75  return;
76  }
77 
78  QDomElement docElem = doc.documentElement();
79  bool notification = false;
80  if (!docElem.isNull())
81  {
82  if (docElem.tagName() != "mythmessage" &&
83  docElem.tagName() != "mythnotification")
84  {
85  LOG(VB_GENERAL, LOG_ERR, LOC +
86  "Unknown UDP packet (not <mythmessage> XML)");
87  return;
88  }
89 
90  if (docElem.tagName() == "mythnotification")
91  {
92  notification = true;
93  }
94 
95  QString version = docElem.attribute("version", "");
96  if (version.isEmpty())
97  {
98  LOG(VB_GENERAL, LOG_ERR, LOC +
99  "<mythmessage> missing 'version' attribute");
100  return;
101  }
102  }
103 
104  QString msg = QString("");
105  uint timeout = 0;
106  QString image;
107  QString origin;
108  QString description = "";
109  QString extra = "";
110  QString progress_text = "";
111  float progress = -1.0F;
112  bool fullscreen = false;
113  bool error = false;
114  int visibility = 0;
115  QString type = "normal";
116 
117  QDomNode n = docElem.firstChild();
118  while (!n.isNull())
119  {
120  QDomElement e = n.toElement();
121  if (!e.isNull())
122  {
123  if (e.tagName() == "text")
124  msg = e.text();
125  else if (e.tagName() == "timeout")
126  timeout = e.text().toUInt();
127  else if (notification && e.tagName() == "image")
128  image = e.text();
129  else if (notification && e.tagName() == "origin")
130  origin = e.text();
131  else if (notification && e.tagName() == "description")
132  description = e.text();
133  else if (notification && e.tagName() == "extra")
134  extra = e.text();
135  else if (notification && e.tagName() == "progress_text")
136  progress_text = e.text();
137  else if (notification && e.tagName() == "fullscreen")
138  fullscreen = e.text().toLower() == "true";
139  else if (notification && e.tagName() == "error")
140  error = e.text().toLower() == "true";
141  else if (e.tagName() == "visibility")
142  visibility = e.text().toUInt();
143  else if (e.tagName() == "type")
144  type = e.text();
145  else if (notification && e.tagName() == "progress")
146  {
147  bool ok = false;
148  progress = e.text().toFloat(&ok);
149  if (!ok)
150  progress = -1.0F;
151  }
152  else
153  {
154  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unknown element: %1")
155  .arg(e.tagName()));
156  }
157  }
158  n = n.nextSibling();
159  }
160 
161  if (!msg.isEmpty() || !image.isEmpty() || !extra.isEmpty())
162  {
163  LOG(VB_GENERAL, LOG_INFO, QString("Received %1 '%2', timeout %3")
164  .arg(notification ? "notification" : "message")
165  .arg(msg).arg(timeout));
166  if (timeout > 1000)
167  timeout = notification ? 5 : 0;
168  if (notification)
169  {
170  origin = origin.isNull() ? tr("UDP Listener") : origin;
173  msg, origin, description, image, extra,
174  progress_text, progress, timeout, fullscreen,
175  visibility);
176  }
177  else
178  {
179  QStringList args;
180  args << QString::number(timeout);
181  MythMainWindow *window = GetMythMainWindow();
182  auto* me = new MythEvent(MythEvent::MythUserMessage, msg, args);
183  qApp->postEvent(window, me);
184  }
185  }
186 }
build_compdb.args
args
Definition: build_compdb.py:11
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1417
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
error
static void error(const char *str,...)
Definition: vbi.cpp:42
ShowNotification
void ShowNotification(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
Definition: mythnotificationcenter.cpp:1439
ServerPool::close
void close(void)
Definition: serverpool.cpp:369
doc
QDomDocument doc("MYTHARCHIVEITEM")
MythNotification::TypeFromString
static Type TypeFromString(const QString &type)
return Type object from type name
Definition: mythnotification.cpp:125
MythUDPListener::Process
static void Process(const QByteArray &buf, const QHostAddress &sender, quint16 senderPort)
Definition: mythudplistener.cpp:62
ServerPool
Manages a collection of sockets listening on different ports.
Definition: serverpool.h:60
progress
bool progress
Definition: mythtv/programs/mythcommflag/main.cpp:74
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:17
arg
arg(title).arg(filename).arg(doDelete))
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythEvent::MythUserMessage
static Type MythUserMessage
Definition: mythevent.h:74
MythNotification::Error
static Type Error
Definition: mythnotification.h:33
mythlogging.h
LOC
#define LOC
Definition: mythudplistener.cpp:12
MythUDPListener::Enable
void Enable(void)
Definition: mythudplistener.cpp:26
ServerPool::DefaultListen
static QList< QHostAddress > DefaultListen(void)
Definition: serverpool.cpp:297
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
ServerPool::bind
bool bind(QList< QHostAddress > addrs, quint16 port, bool requireall=true)
Definition: serverpool.cpp:492
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:930
MythUDPListener::MythUDPListener
MythUDPListener()
Definition: mythudplistener.cpp:14
mythcorecontext.h
MythUDPListener::Disable
void Disable(void)
Definition: mythudplistener.cpp:50
mythudplistener.h
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:107
MythUDPListener::m_socketPool
ServerPool * m_socketPool
Definition: mythudplistener.h:35
ServerPool::DefaultBroadcast
static QList< QHostAddress > DefaultBroadcast(void)
Definition: serverpool.cpp:333
mythmainwindow.h
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:81
MythMainWindow
Definition: mythmainwindow.h:33
MythUDPListener::deleteLater
virtual void deleteLater(void)
Definition: mythudplistener.cpp:19