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;
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 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
197 QStringList tokens = line.split(
' ', QString::SkipEmptyParts);
199 QStringList tokens = line.split(
' ', Qt::SkipEmptyParts);
201 QString command = tokens[0];
203 bool handled =
false;
206 if (command ==
"DONE")
216 if (command ==
"MYTH_PROTO_VERSION")
222 LOG(VB_SOCKET, LOG_ERR,
LOC +
223 "Use of socket attempted before protocol validation.");
225 listline <<
"ERROR" <<
"socket has not been validated";
235 if (command ==
"ANN")
239 QMap<QString, SocketRequestHandler*>::const_iterator i
243 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
244 QString(
"Attempting to handle announce with: %1")
245 .arg((*i)->GetHandlerName()));
246 handled = (*i)->HandleAnnounce(sock, tokens, listline);
253 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
254 QString(
"Socket announce handled by: %1")
255 .arg((*i)->GetHandlerName()));
258 (*i)->connectionAnnounced(sock, tokens, listline);
262 LOG(VB_SOCKET, LOG_ERR,
LOC +
"Socket announce unhandled.");
264 listline <<
"ERROR" <<
"unhandled announce";
270 LOG(VB_SOCKET, LOG_ERR,
LOC +
271 "Use of socket attempted before announcement.");
273 listline <<
"ERROR" <<
"socket has not been announced";
278 if (command ==
"ANN")
280 LOG(VB_SOCKET, LOG_ERR,
LOC +
"ANN sent out of sequence.");
282 listline <<
"ERROR" <<
"socket has already been announced";
294 LOG(VB_SOCKET, LOG_ERR,
LOC +
"No handler found for socket.");
296 listline <<
"ERROR" <<
"socket handler cannot be found";
304 QMap<QString, SocketRequestHandler*>::const_iterator i
308 handled = (*i)->HandleQuery(handler, tokens, listline);
313 LOG(VB_SOCKET, LOG_DEBUG,
LOC + QString(
"Query handled by: %1")
314 .arg((*--i)->GetHandlerName()));
319 if (command ==
"BACKEND_MESSAGE")
327 listline <<
"ERROR" <<
"unknown command";
333 const QStringList &slist)
336 const QString&
version = slist[1];
337 if (
version != MYTH_PROTO_VERSION)
339 LOG(VB_GENERAL, LOG_ERR,
LOC +
340 "Client speaks protocol version " +
version +
341 " but we speak " + MYTH_PROTO_VERSION +
'!');
342 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
348 if (slist.size() < 3)
350 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Client did not pass protocol "
351 "token. Refusing connection!");
352 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
358 const QString& token = slist[2];
359 if (token != QString::fromUtf8(MYTH_PROTO_TOKEN))
361 LOG(VB_GENERAL, LOG_ERR,
LOC +
362 QString(
"Client sent incorrect protocol token \"%1\" for "
363 "protocol version. Refusing connection!").arg(token));
364 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
370 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
"Client validated");
371 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