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 QStringList tokens = line.split(
' ', Qt::SkipEmptyParts);
198 QString command = tokens[0];
200 bool handled =
false;
203 if (command ==
"DONE")
213 if (command ==
"MYTH_PROTO_VERSION")
219 LOG(VB_SOCKET, LOG_ERR,
LOC +
220 "Use of socket attempted before protocol validation.");
222 listline <<
"ERROR" <<
"socket has not been validated";
232 if (command ==
"ANN")
236 QMap<QString, SocketRequestHandler*>::const_iterator i
240 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
241 QString(
"Attempting to handle announce with: %1")
242 .arg((*i)->GetHandlerName()));
243 handled = (*i)->HandleAnnounce(sock, tokens, listline);
250 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
251 QString(
"Socket announce handled by: %1")
252 .arg((*i)->GetHandlerName()));
255 (*i)->connectionAnnounced(sock, tokens, listline);
259 LOG(VB_SOCKET, LOG_ERR,
LOC +
"Socket announce unhandled.");
261 listline <<
"ERROR" <<
"unhandled announce";
267 LOG(VB_SOCKET, LOG_ERR,
LOC +
268 "Use of socket attempted before announcement.");
270 listline <<
"ERROR" <<
"socket has not been announced";
275 if (command ==
"ANN")
277 LOG(VB_SOCKET, LOG_ERR,
LOC +
"ANN sent out of sequence.");
279 listline <<
"ERROR" <<
"socket has already been announced";
291 LOG(VB_SOCKET, LOG_ERR,
LOC +
"No handler found for socket.");
293 listline <<
"ERROR" <<
"socket handler cannot be found";
301 QMap<QString, SocketRequestHandler*>::const_iterator i
305 handled = (*i)->HandleQuery(handler, tokens, listline);
310 LOG(VB_SOCKET, LOG_DEBUG,
LOC + QString(
"Query handled by: %1")
311 .arg((*--i)->GetHandlerName()));
316 if (command ==
"BACKEND_MESSAGE")
324 listline <<
"ERROR" <<
"unknown command";
330 const QStringList &slist)
333 const QString&
version = slist[1];
334 if (
version != MYTH_PROTO_VERSION)
336 LOG(VB_GENERAL, LOG_ERR,
LOC +
337 "Client speaks protocol version " +
version +
338 " but we speak " + MYTH_PROTO_VERSION +
'!');
339 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
345 if (slist.size() < 3)
347 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Client did not pass protocol "
348 "token. Refusing connection!");
349 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
355 const QString& token = slist[2];
356 if (token != QString::fromUtf8(MYTH_PROTO_TOKEN))
358 LOG(VB_GENERAL, LOG_ERR,
LOC +
359 QString(
"Client sent incorrect protocol token \"%1\" for "
360 "protocol version. Refusing connection!").arg(token));
361 retlist <<
"REJECT" << MYTH_PROTO_VERSION;
367 LOG(VB_SOCKET, LOG_DEBUG,
LOC +
"Client validated");
368 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