diff --git a/libraries/networking/src/SequenceNumberStats.cpp b/libraries/networking/src/SequenceNumberStats.cpp index 6a7f5e1964..f472159164 100644 --- a/libraries/networking/src/SequenceNumberStats.cpp +++ b/libraries/networking/src/SequenceNumberStats.cpp @@ -253,14 +253,19 @@ PacketStreamStats SequenceNumberStats::getStatsForHistoryWindow() const { } // calculate difference between newest stats and oldest stats to get window stats - PacketStreamStats windowStats; - windowStats._received = newestStats->_received - oldestStats->_received; - windowStats._unreasonable = newestStats->_unreasonable - oldestStats->_unreasonable; - windowStats._early = newestStats->_early - oldestStats->_early; - windowStats._late = newestStats->_late - oldestStats->_late; - windowStats._lost = newestStats->_lost - oldestStats->_lost; - windowStats._recovered = newestStats->_recovered - oldestStats->_recovered; - windowStats._expectedReceived = newestStats->_expectedReceived - oldestStats->_expectedReceived; - - return windowStats; + return *newestStats - *oldestStats; } + +PacketStreamStats SequenceNumberStats::getStatsForLastHistoryInterval() const { + + const PacketStreamStats* newestStats = _statsHistory.getNewestEntry(); + const PacketStreamStats* secondNewestStats = _statsHistory.get(1); + + // this catches cases where history is length 1 or 0 (both are NULL in case of 0) + if (newestStats == NULL || secondNewestStats == NULL) { + return PacketStreamStats(); + } + + return *newestStats - *secondNewestStats; +} + diff --git a/libraries/networking/src/SequenceNumberStats.h b/libraries/networking/src/SequenceNumberStats.h index 5e02dbc850..434d5a18db 100644 --- a/libraries/networking/src/SequenceNumberStats.h +++ b/libraries/networking/src/SequenceNumberStats.h @@ -31,6 +31,18 @@ public: _expectedReceived(0) {} + PacketStreamStats operator-(const PacketStreamStats& rhs) const { + PacketStreamStats diff; + diff._received = _received - rhs._received; + diff._unreasonable = _unreasonable - rhs._unreasonable; + diff._early = _early - rhs._early; + diff._late = _late - rhs._late; + diff._lost = _lost - rhs._lost; + diff._recovered = _recovered - rhs._recovered; + diff._expectedReceived = _expectedReceived - rhs._expectedReceived; + return diff; + } + float getLostRate() const { return (float)_lost / _expectedReceived; } quint32 _received; @@ -76,6 +88,7 @@ public: const PacketStreamStats& getStats() const { return _stats; } PacketStreamStats getStatsForHistoryWindow() const; + PacketStreamStats getStatsForLastHistoryInterval() const; const QSet& getMissingSet() const { return _missingSet; } private: diff --git a/tests/jitter/src/main.cpp b/tests/jitter/src/main.cpp index c4e6472439..bb6d902e86 100644 --- a/tests/jitter/src/main.cpp +++ b/tests/jitter/src/main.cpp @@ -16,6 +16,7 @@ #include #include // for MovingMinMaxAvg +#include #include // for usecTimestampNow const quint64 MSEC_TO_USEC = 1000; @@ -61,6 +62,8 @@ void runSend(const char* addressOption, int port, int gap, int size, int report) char* outputBuffer = new char[size]; memset(outputBuffer, 0, size); + + quint16 outgoingSequenceNumber = 0; sockfd=socket(AF_INET,SOCK_DGRAM,0); @@ -91,7 +94,12 @@ void runSend(const char* addressOption, int port, int gap, int size, int report) if (actualGap >= gap) { + + // pack seq num + memcpy(outputBuffer, &outgoingSequenceNumber, sizeof(quint16)); + sendto(sockfd, outputBuffer, size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); + outgoingSequenceNumber++; int gapDifferece = actualGap - gap; timeGaps.update(gapDifferece); @@ -148,6 +156,12 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo std::cout << "SAMPLES_PER_REPORT:" << SAMPLES_PER_REPORT << "\n"; MovingMinMaxAvg timeGapsPerReport(1, SAMPLES_PER_REPORT); + + const int REPORTS_FOR_30_SECONDS = 30 * MSECS_PER_SECOND / report; + + std::cout << "REPORTS_FOR_30_SECONDS:" << REPORTS_FOR_30_SECONDS << "\n"; + + SequenceNumberStats seqStats(REPORTS_FOR_30_SECONDS); if (bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { std::cout << "bind failed\n"; @@ -159,6 +173,10 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo while (true) { n = recvfrom(sockfd, inputBuffer, size, 0, NULL, NULL); // we don't care about where it came from + + // parse seq num + quint16 incomingSequenceNumber = *(reinterpret_cast(inputBuffer)); + seqStats.sequenceNumberReceived(incomingSequenceNumber); if (last == 0) { last = usecTimestampNow(); @@ -172,6 +190,9 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo last = now; if (now - lastReport >= (report * MSEC_TO_USEC)) { + + seqStats.pushStatsToHistory(); + std::cout << "RECEIVE gap Difference From Expected " << "Overall:\n" << "min: " << timeGaps.getMin() << " usecs, " @@ -187,6 +208,21 @@ void runReceive(const char* addressOption, int port, int gap, int size, int repo << "avg: " << timeGapsPerReport.getWindowAverage() << " usecs\n" << "\n"; + PacketStreamStats packetStatsLast30s = seqStats.getStatsForHistoryWindow(); + PacketStreamStats packetStatsLastReportInterval = seqStats.getStatsForLastHistoryInterval(); + + std::cout << "RECEIVE Packet Stats " + << "Overall:\n" + << "lost: " << seqStats.getLost() << ", " + << "lost %: " << seqStats.getStats().getLostRate() * 100.0f << "%\n" + << "Last 30s:\n" + << "lost: " << packetStatsLast30s._lost << ", " + << "lost %: " << packetStatsLast30s.getLostRate() * 100.0f << "%\n" + << "Last report interval:\n" + << "lost: " << packetStatsLastReportInterval._lost << ", " + << "lost %: " << packetStatsLastReportInterval.getLostRate() * 100.0f << "%\n" + << "\n\n"; + lastReport = now; } }