Go to the documentation of this file.
3 #include <QReadWriteLock>
5 #include <QWriteLocker>
6 #include <QMutexLocker>
7 #include <QWaitCondition>
9 #include <QCoreApplication>
10 #include <QNetworkProxy>
15 #include "libmythbase/mythconfig.h"
18 #include "libmythbase/mythversion.h"
26 #define LOC QString("MythSocketManager: ")
28 static constexpr std::chrono::milliseconds
PRT_TIMEOUT { 10ms };
39 void run(
void)
override
51 m_threadPool(
"MythSocketManager")
61 QMap<QString, SocketRequestHandler*>::iterator i;
89 LOG(VB_GENERAL, LOG_ERR, QString(
"Failed to bind port %1.").arg(port));
102 if (ms->IsConnected())
115 LOG(VB_GENERAL, LOG_WARNING,
LOC + name +
116 " has already been registered.");
121 LOG(VB_GENERAL, LOG_INFO,
LOC +
122 "Registering socket command handler " + name);
164 QMap<QString, SocketRequestHandler*>::const_iterator i;
166 (*i)->connectionClosed(sock);
192 QStringList listline;
196 QString line = listline[0].simplified();
197 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
198 QStringList tokens = line.split(
' ', QString::SkipEmptyParts);
200 QStringList tokens = line.split(
' ', Qt::SkipEmptyParts);
202 QString command = tokens[0];
204 bool handled =
false;
207 if (command ==
"DONE")
217 if (command ==
"MYTH_PROTO_VERSION")
223 LOG(VB_SOCKET, LOG_ERR,
LOC +
224 "Use of socket attempted before protocol validation.");
226 listline <<
"ERROR" <<
"socket has not been validated";
236 if (command ==
"ANN")
240 QMap<QString, SocketRequestHandler*>::const_iterator i
244 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
245 QString(
"Attempting to handle announce with: %1")
246 .arg((*i)->GetHandlerName()));
247 handled = (*i)->HandleAnnounce(sock, tokens, listline);
254 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
255 QString(
"Socket announce handled by: %1")
256 .arg((*i)->GetHandlerName()));
259 (*i)->connectionAnnounced(sock, tokens, listline);
263 LOG(VB_SOCKET, LOG_ERR,
LOC +
"Socket announce unhandled.");
265 listline <<
"ERROR" <<
"unhandled announce";
271 LOG(VB_SOCKET, LOG_ERR,
LOC +
272 "Use of socket attempted before announcement.");
274 listline <<
"ERROR" <<
"socket has not been announced";
279 if (command ==
"ANN")
281 LOG(VB_SOCKET, LOG_ERR,
LOC +
"ANN sent out of sequence.");
283 listline <<
"ERROR" <<
"socket has already been announced";
295 LOG(VB_SOCKET, LOG_ERR,
LOC +
"No handler found for socket.");
297 listline <<
"ERROR" <<
"socket handler cannot be found";
305 QMap<QString, SocketRequestHandler*>::const_iterator i
309 handled = (*i)->HandleQuery(handler, tokens, listline);
314 LOG(VB_SOCKET, LOG_DEBUG,
LOC + QString(
"Query handled by: %1")
315 .arg((*--i)->GetHandlerName()));
320 if (command ==
"BACKEND_MESSAGE")
328 listline <<
"ERROR" <<
"unknown command";
334 const QStringList &slist)
337 const QString&
version = slist[1];
338 if (
version != MYTH_PROTO_VERSION)
340 LOG(VB_GENERAL, LOG_ERR,
LOC +
341 "Client speaks protocol version " +
version +
342 " but we speak " + MYTH_PROTO_VERSION +
'!');
343 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
349 if (slist.size() < 3)
351 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Client did not pass protocol "
352 "token. Refusing connection!");
353 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
359 const QString& token = slist[2];
360 if (token != QString::fromUtf8(MYTH_PROTO_TOKEN))
362 LOG(VB_GENERAL, LOG_ERR,
LOC +
363 QString(
"Client sent incorrect protocol token \"%1\" for "
364 "protocol version. Refusing connection!").arg(token));
365 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
371 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
"Client validated");
372 retlist <<
"ACCEPT" << MYTH_PROTO_VERSION;
This decrements the reference on destruction.
void newConnection(qintptr sd)
static constexpr std::chrono::milliseconds PRT_TIMEOUT
void readyRead(MythSocket *socket) override
~MythSocketManager() override
static void HandleDone(MythSocket *socket)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual QString GetHandlerName(void)
bool IsAnnounced(void) const
bool IsValidated(void) const
void DisconnectFromHost(void)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void startReserved(QRunnable *runnable, const QString &debugName, std::chrono::milliseconds waitForAvailMS=0ms)
ProcessRequestRunnable(MythSocketManager &parent, MythSocket *sock)
QMap< MythSocket *, SocketHandler * > m_socketMap
Class for communcating between myth backends and frontends.
void RegisterHandler(SocketRequestHandler *handler)
bool WriteStringList(const QStringList &list)
MythSocket * GetSocket(void)
void AddSocketHandler(SocketHandler *socket)
virtual void SetParent(MythSocketManager *parent)
QSet< MythSocket * > m_socketList
QReadWriteLock m_socketLock
void ProcessRequestWork(MythSocket *socket)
QMap< QString, SocketRequestHandler * > m_handlerMap
SocketHandler * GetConnectionBySocket(MythSocket *socket)
bool IsDataAvailable(void)
QReadWriteLock m_handlerLock
bool listen(QList< QHostAddress > addrs, quint16 port, bool requireall=true, PoolServerType type=kTCPServer)
static void HandleVersion(MythSocket *socket, const QStringList &slist)
void ProcessRequest(MythSocket *socket)
MythSocketManager & m_parent
void newConnection(qintptr socket)
virtual int IncrRef(void)
Increments reference count.
void setProxy(const QNetworkProxy &proxy)
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
void connectionClosed(MythSocket *socket) override