3#include <QReadWriteLock>
7#include <QWaitCondition>
9#include <QCoreApplication>
10#include <QNetworkProxy>
15#include "libmythbase/mythconfig.h"
17#include "libmythbase/mythversion.h"
25#define LOC QString("MythSocketManager: ")
27static constexpr std::chrono::milliseconds
PRT_TIMEOUT { 10ms };
38 void run(
void)
override
50 m_threadPool(
"MythSocketManager")
60 QMap<QString, SocketRequestHandler*>::iterator i;
88 LOG(VB_GENERAL, LOG_ERR, QString(
"Failed to bind port %1.").arg(port));
101 if (ms->IsConnected())
114 LOG(VB_GENERAL, LOG_WARNING,
LOC + name +
115 " has already been registered.");
120 LOG(VB_GENERAL, LOG_INFO,
LOC +
121 "Registering socket command handler " + name);
163 QMap<QString, SocketRequestHandler*>::const_iterator i;
165 (*i)->connectionClosed(sock);
191 QStringList listline;
195 QString line = listline[0].simplified();
196 QStringList tokens = line.split(
' ', Qt::SkipEmptyParts);
197 QString command = tokens[0];
199 bool handled =
false;
202 if (command ==
"DONE")
212 if (command ==
"MYTH_PROTO_VERSION")
218 LOG(VB_SOCKET, LOG_ERR,
LOC +
219 "Use of socket attempted before protocol validation.");
221 listline <<
"ERROR" <<
"socket has not been validated";
231 if (command ==
"ANN")
235 QMap<QString, SocketRequestHandler*>::const_iterator i
239 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
240 QString(
"Attempting to handle announce with: %1")
241 .arg((*i)->GetHandlerName()));
242 handled = (*i)->HandleAnnounce(sock, tokens, listline);
249 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
250 QString(
"Socket announce handled by: %1")
251 .arg((*i)->GetHandlerName()));
254 (*i)->connectionAnnounced(sock, tokens, listline);
258 LOG(VB_SOCKET, LOG_ERR,
LOC +
"Socket announce unhandled.");
260 listline <<
"ERROR" <<
"unhandled announce";
266 LOG(VB_SOCKET, LOG_ERR,
LOC +
267 "Use of socket attempted before announcement.");
269 listline <<
"ERROR" <<
"socket has not been announced";
274 if (command ==
"ANN")
276 LOG(VB_SOCKET, LOG_ERR,
LOC +
"ANN sent out of sequence.");
278 listline <<
"ERROR" <<
"socket has already been announced";
290 LOG(VB_SOCKET, LOG_ERR,
LOC +
"No handler found for socket.");
292 listline <<
"ERROR" <<
"socket handler cannot be found";
300 QMap<QString, SocketRequestHandler*>::const_iterator i
304 handled = (*i)->HandleQuery(handler, tokens, listline);
309 LOG(VB_SOCKET, LOG_DEBUG,
LOC + QString(
"Query handled by: %1")
310 .arg((*--i)->GetHandlerName()));
315 if (command ==
"BACKEND_MESSAGE")
323 listline <<
"ERROR" <<
"unknown command";
329 const QStringList &slist)
332 const QString&
version = slist[1];
333 if (
version != MYTH_PROTO_VERSION)
335 LOG(VB_GENERAL, LOG_ERR,
LOC +
336 "Client speaks protocol version " +
version +
337 " but we speak " + MYTH_PROTO_VERSION +
'!');
338 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
344 if (slist.size() < 3)
346 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Client did not pass protocol "
347 "token. Refusing connection!");
348 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
354 const QString& token = slist[2];
355 if (token != QString::fromUtf8(MYTH_PROTO_TOKEN))
357 LOG(VB_GENERAL, LOG_ERR,
LOC +
358 QString(
"Client sent incorrect protocol token \"%1\" for "
359 "protocol version. Refusing connection!").arg(token));
360 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
366 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
"Client validated");
367 retlist <<
"ACCEPT" << MYTH_PROTO_VERSION;
void startReserved(QRunnable *runnable, const QString &debugName, std::chrono::milliseconds waitForAvailMS=0ms)
void newConnection(qintptr socket)
QMap< QString, SocketRequestHandler * > m_handlerMap
static void HandleVersion(MythSocket *socket, const QStringList &slist)
SocketHandler * GetConnectionBySocket(MythSocket *socket)
QReadWriteLock m_handlerLock
void readyRead(MythSocket *socket) override
QReadWriteLock m_socketLock
void AddSocketHandler(SocketHandler *socket)
~MythSocketManager() override
void ProcessRequestWork(MythSocket *socket)
void ProcessRequest(MythSocket *socket)
void RegisterHandler(SocketRequestHandler *handler)
void newConnection(qintptr sd)
static void HandleDone(MythSocket *socket)
void connectionClosed(MythSocket *socket) override
QMap< MythSocket *, SocketHandler * > m_socketMap
QSet< MythSocket * > m_socketList
Class for communcating between myth backends and frontends.
bool IsValidated(void) const
bool IsAnnounced(void) const
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
bool IsDataAvailable(void)
void DisconnectFromHost(void)
bool WriteStringList(const QStringList &list)
ProcessRequestRunnable(MythSocketManager &parent, MythSocket *sock)
MythSocketManager & m_parent
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
This decrements the reference on destruction.
bool listen(QList< QHostAddress > addrs, quint16 port, bool requireall=true, PoolServerType type=kTCPServer)
void setProxy(const QNetworkProxy &proxy)
MythSocket * GetSocket(void) const
virtual void SetParent(MythSocketManager *parent)
virtual QString GetHandlerName(void)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static constexpr std::chrono::milliseconds PRT_TIMEOUT