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);
36 
37  QList<QHostAddress> addrs = ServerPool::DefaultListen();
39 
40  if (!m_socketPool->bind(addrs,
41  gCoreContext->GetNumSetting("UDPNotifyPort", 0), false))
42  {
43  delete m_socketPool;
44  m_socketPool = nullptr;
45  }
46 }
47 
49 {
50  if (!m_socketPool)
51  return;
52 
53  LOG(VB_GENERAL, LOG_INFO, LOC + "Disabling");
54 
56  delete m_socketPool;
57  m_socketPool = nullptr;
58 }
59 
60 void MythUDPListener::Process(const QByteArray &buf, const QHostAddress& /*sender*/,
61  quint16 /*senderPort*/)
62 {
63  QString errorMsg;
64  int errorLine = 0;
65  int errorColumn = 0;
66  QDomDocument doc;
67  if (!doc.setContent(buf, false, &errorMsg, &errorLine, &errorColumn))
68  {
69  LOG(VB_GENERAL, LOG_ERR, LOC +
70  QString("Parsing xml:\n\t\t\t at line: %1 column: %2\n\t\t\t%3")
71  .arg(errorLine).arg(errorColumn).arg(errorMsg));
72 
73  return;
74  }
75 
76  QDomElement docElem = doc.documentElement();
77  bool notification = false;
78  if (!docElem.isNull())
79  {
80  if (docElem.tagName() != "mythmessage" &&
81  docElem.tagName() != "mythnotification")
82  {
83  LOG(VB_GENERAL, LOG_ERR, LOC +
84  "Unknown UDP packet (not <mythmessage> XML)");
85  return;
86  }
87 
88  if (docElem.tagName() == "mythnotification")
89  {
90  notification = true;
91  }
92 
93  QString version = docElem.attribute("version", "");
94  if (version.isEmpty())
95  {
96  LOG(VB_GENERAL, LOG_ERR, LOC +
97  "<mythmessage> missing 'version' attribute");
98  return;
99  }
100  }
101 
102  QString msg = QString("");
103  uint timeout = 0;
104  QString image;
105  QString origin;
106  QString description = "";
107  QString extra = "";
108  QString progress_text = "";
109  float progress = -1.0F;
110  bool fullscreen = false;
111  bool error = false;
112  int visibility = 0;
113  QString type = "normal";
114 
115  QDomNode n = docElem.firstChild();
116  while (!n.isNull())
117  {
118  QDomElement e = n.toElement();
119  if (!e.isNull())
120  {
121  if (e.tagName() == "text")
122  msg = e.text();
123  else if (e.tagName() == "timeout")
124  timeout = e.text().toUInt();
125  else if (notification && e.tagName() == "image")
126  image = e.text();
127  else if (notification && e.tagName() == "origin")
128  origin = e.text();
129  else if (notification && e.tagName() == "description")
130  description = e.text();
131  else if (notification && e.tagName() == "extra")
132  extra = e.text();
133  else if (notification && e.tagName() == "progress_text")
134  progress_text = e.text();
135  else if (notification && e.tagName() == "fullscreen")
136  fullscreen = e.text().toLower() == "true";
137  else if (notification && e.tagName() == "error")
138  error = e.text().toLower() == "true";
139  else if (e.tagName() == "visibility")
140  visibility = e.text().toUInt();
141  else if (e.tagName() == "type")
142  type = e.text();
143  else if (notification && e.tagName() == "progress")
144  {
145  bool ok = false;
146  progress = e.text().toFloat(&ok);
147  if (!ok)
148  progress = -1.0F;
149  }
150  else
151  {
152  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unknown element: %1")
153  .arg(e.tagName()));
154  }
155  }
156  n = n.nextSibling();
157  }
158 
159  if (!msg.isEmpty() || !image.isEmpty() || !extra.isEmpty())
160  {
161  LOG(VB_GENERAL, LOG_INFO, QString("Received %1 '%2', timeout %3")
162  .arg(notification ? "notification" : "message")
163  .arg(msg).arg(timeout));
164  if (timeout > 1000)
165  timeout = notification ? 5 : 0;
166  if (notification)
167  {
168  origin = origin.isNull() ? tr("UDP Listener") : origin;
171  msg, origin, description, image, extra,
172  progress_text, progress, timeout, fullscreen,
173  visibility);
174  }
175  else
176  {
177  QStringList args;
178  args << QString::number(timeout);
179  MythMainWindow *window = GetMythMainWindow();
180  auto* me = new MythEvent(MythEvent::MythUserMessage, msg, args);
181  qApp->postEvent(window, me);
182  }
183  }
184 }
build_compdb.args
args
Definition: build_compdb.py:11
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
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::newDatagram
void newDatagram(QByteArray, QHostAddress, quint16)
ServerPool::close
void close(void)
Definition: serverpool.cpp:367
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:60
ServerPool
Manages a collection of sockets listening on different ports.
Definition: serverpool.h:60
progress
bool progress
Definition: mythtv/programs/mythcommflag/main.cpp:73
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:298
uint
unsigned int uint
Definition: compat.h:141
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
ServerPool::bind
bool bind(QList< QHostAddress > addrs, quint16 port, bool requireall=true)
Definition: serverpool.cpp:487
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:933
MythUDPListener::MythUDPListener
MythUDPListener()
Definition: mythudplistener.cpp:14
mythcorecontext.h
MythUDPListener::Disable
void Disable(void)
Definition: mythudplistener.cpp:48
mythudplistener.h
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:108
MythUDPListener::m_socketPool
ServerPool * m_socketPool
Definition: mythudplistener.h:35
ServerPool::DefaultBroadcast
static QList< QHostAddress > DefaultBroadcast(void)
Definition: serverpool.cpp:332
mythmainwindow.h
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:81
MythMainWindow
Definition: mythmainwindow.h:35
MythUDPListener::deleteLater
virtual void deleteLater(void)
Definition: mythudplistener.cpp:19