00001 #include <QCoreApplication>
00002 #include <QUdpSocket>
00003 #include <QDomDocument>
00004 #include <QList>
00005 #include <QHostAddress>
00006
00007 #include "mythcorecontext.h"
00008 #include "mythlogging.h"
00009 #include "mythmainwindow.h"
00010 #include "mythudplistener.h"
00011
00012 #define LOC QString("UDPListener: ")
00013
00014 MythUDPListener::MythUDPListener()
00015 {
00016 m_socketPool = new ServerPool(this);
00017 connect(m_socketPool, SIGNAL(newDatagram(QByteArray, QHostAddress,
00018 quint16)),
00019 this, SLOT(Process(const QByteArray, QHostAddress,
00020 quint16)));
00021
00022 QList<QHostAddress> addrs = ServerPool::DefaultListen();
00023 addrs << ServerPool::DefaultBroadcast();
00024
00025 if (!m_socketPool->bind(addrs,
00026 gCoreContext->GetNumSetting("UDPNotifyPort", 0), false))
00027 {
00028 delete m_socketPool;
00029 m_socketPool = NULL;
00030 }
00031 }
00032
00033 void MythUDPListener::deleteLater(void)
00034 {
00035 TeardownAll();
00036 disconnect();
00037 QObject::deleteLater();
00038 }
00039
00040 void MythUDPListener::TeardownAll(void)
00041 {
00042 if (!m_socketPool)
00043 return;
00044
00045 LOG(VB_GENERAL, LOG_INFO, LOC + "Disconnecting");
00046
00047 m_socketPool->close();
00048 delete m_socketPool;
00049 m_socketPool = NULL;
00050 }
00051
00052 void MythUDPListener::Process(const QByteArray &buf, QHostAddress sender,
00053 quint16 senderPort)
00054 {
00055 QString errorMsg;
00056 int errorLine = 0;
00057 int errorColumn = 0;
00058 QDomDocument doc;
00059 if (!doc.setContent(buf, false, &errorMsg, &errorLine, &errorColumn))
00060 {
00061 LOG(VB_GENERAL, LOG_ERR, LOC +
00062 QString("Parsing xml:\n\t\t\t at line: %1 column: %2\n\t\t\t%3")
00063 .arg(errorLine).arg(errorColumn).arg(errorMsg));
00064
00065 return;
00066 }
00067
00068 QDomElement docElem = doc.documentElement();
00069 if (!docElem.isNull())
00070 {
00071 if (docElem.tagName() != "mythmessage")
00072 {
00073 LOG(VB_GENERAL, LOG_ERR, LOC +
00074 "Unknown UDP packet (not <mythmessage> XML)");
00075 return;
00076 }
00077
00078 QString version = docElem.attribute("version", "");
00079 if (version.isEmpty())
00080 {
00081 LOG(VB_GENERAL, LOG_ERR, LOC +
00082 "<mythmessage> missing 'version' attribute");
00083 return;
00084 }
00085 }
00086
00087 QString msg = QString("");
00088 uint timeout = 0;
00089
00090 QDomNode n = docElem.firstChild();
00091 while (!n.isNull())
00092 {
00093 QDomElement e = n.toElement();
00094 if (!e.isNull())
00095 {
00096 if (e.tagName() == "text")
00097 msg = e.text();
00098 else if (e.tagName() == "timeout")
00099 timeout = e.text().toUInt();
00100 else
00101 {
00102 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unknown element: %1")
00103 .arg(e.tagName()));
00104 return;
00105 }
00106 }
00107 n = n.nextSibling();
00108 }
00109
00110 if (!msg.isEmpty())
00111 {
00112 if (timeout > 1000)
00113 timeout = 0;
00114 LOG(VB_GENERAL, LOG_INFO, QString("Received message '%1', timeout %2")
00115 .arg(msg).arg(timeout));
00116 QStringList args;
00117 args << QString::number(timeout);
00118 MythMainWindow *window = GetMythMainWindow();
00119 MythEvent* me = new MythEvent(MythEvent::MythUserMessage, msg, args);
00120 qApp->postEvent(window, me);
00121 }
00122 }