aboutsummaryrefslogtreecommitdiff
path: root/src/UdpTasks/StatusChecker/onticker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/UdpTasks/StatusChecker/onticker.cpp')
-rw-r--r--src/UdpTasks/StatusChecker/onticker.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/UdpTasks/StatusChecker/onticker.cpp b/src/UdpTasks/StatusChecker/onticker.cpp
new file mode 100644
index 0000000..e4a8fb2
--- /dev/null
+++ b/src/UdpTasks/StatusChecker/onticker.cpp
@@ -0,0 +1,81 @@
+#include "statuschecker.h"
+
+void StatusChecker::onTicker()
+{
+
+ // get next recent item from database (id > index)
+ QSqlQuery q = getNextServer(_dbIndex);
+
+ if ( q.next() )
+ {
+ // get serverinfo from query
+ _dbIndex = q.value("id").toInt();
+ QString remoteAddress = q.value("ip").toString();
+ unsigned short remotePort = static_cast<unsigned short>(q.value("queryport").toInt());
+ QString gamename = q.value("gamename").toString();
+ bool authenticated = static_cast<unsigned short>(q.value("f_auth").toBool());
+
+ // if this particular server was added through SYNC, it may not yet have been authenticated.
+ // send secure/validate challenge in that case
+ if ( ! authenticated )
+ {
+ // shorthand label
+ QString remoteAddressLabel = QStringLiteral("%1:%2").arg(remoteAddress, QString::number(remotePort));
+ QString secure = genChallengeString(6, false);
+
+ // use HeartBeat struct to cache gamename+secure
+ // TODO optimise the HeartBeat struct in BeaconServer to cater both purposes
+ UdpData secureInfo;
+ secureInfo.secure = secure;
+ secureInfo.gamename = gamename;
+ _secureBuffer.insert(remoteAddressLabel, secureInfo);
+
+ // send secure challenge
+ QString udpSecure = QStringLiteral("\\secure\\%1").arg(secure);
+ QNetworkDatagram udpSecureDatagram(udpSecure.toUtf8(), QHostAddress(remoteAddress), remotePort);
+ _udpSocket.writeDatagram(udpSecureDatagram);
+ }
+
+ // create datagram with info- or status request
+ QNetworkDatagram udpDatagram(_udpRequest.toUtf8(), QHostAddress(remoteAddress), remotePort);
+
+ // and send
+ _udpSocket.writeDatagram(udpDatagram);
+
+ // readyRead miss workaround
+ if ( _udpSocket.hasPendingDatagrams() )
+ {
+ /* WORKAROUND INFO
+ * _udpSocket.bytesAvailable() > 0 and _udpSocket.hasPendingDatagrams(),
+ * but apparently no readyRead signal was emitted. As a result, incoming data
+ * is no longer processed. Temporary fix until the cause has been found:
+ * emit readyRead manually when datagrams are available. It is still possible
+ * that the ticker is faster than the readyRead-bound function and that readyRead
+ * was issued correctly, so we count two ticks of missed read calls. If the
+ * readyRead signal was correctly issued, the onUdpResponseRead function will
+ * reset the missed readcall counter. Even when botched, it is better to emit the
+ * same signal twice, rather than not at all (onUdpResponseRead has a failsaife
+ * for duplicate/redundant calls).
+ *
+ * Other info:
+ * is this related to https://www.qtcentre.org/threads/64370-QUdpSocket-readyRead-failure ?
+ *
+ * Displaying readyread state and available data:
+ qDebug() << "bytes available: "
+ << _udpSocket.bytesAvailable()
+ << "pending datagrams: "
+ << _udpSocket.hasPendingDatagrams()
+ ;
+ */
+ _missedReadCalls++;
+
+ // two missed calls in 2 ticks, emit signal manually
+ if ( _missedReadCalls >= 2)
+ {
+ _coreObject->Log.logEvent("warning", "checker udp data not signalled: emitting readyread manually");
+ emit _udpSocket.readyRead();
+ }
+ } // end workaround
+
+ } // end next
+}