From bdca404457c1c1dd9dcafc4645126e913657afe1 Mon Sep 17 00:00:00 2001 From: Phil Taylor Date: Wed, 4 May 2022 20:21:29 +0100 Subject: [PATCH] Make udpserver and client behave the same way for retransmit --- udphandler.cpp | 51 +++++++++++++++++++++----------------------------- udpserver.cpp | 19 ++++++++++--------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/udphandler.cpp b/udphandler.cpp index abcc9b0..cc21e9d 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -202,7 +202,7 @@ void udpHandler::dataReceived() } QString tempLatency; - if (status.rxLatency > status.rxCurrentLatency && !status.rxUnderrun) + if (status.rxCurrentLatency < status.rxLatency*1.2 && !status.rxUnderrun) { tempLatency = QString("%1 ms").arg(status.rxCurrentLatency,3); } @@ -1199,7 +1199,7 @@ void udpBase::dataReceived(QByteArray r) case (CONTROL_SIZE): // Empty response used for simple comms and retransmit requests. { control_packet_t in = (control_packet_t)r.constData(); - if (in->type == 0x01) + if (in->type == 0x01 && in->len == 0x10) { // Single packet request packetsLost++; @@ -1210,7 +1210,7 @@ void udpBase::dataReceived(QByteArray r) // Found matching entry? // Send "untracked" as it has already been sent once. // Don't constantly retransmit the same packet, give-up eventually - qDebug(logUdp()) << this->metaObject()->className() << ": Sending retransmit of " << QString("0x%1").arg(match->seqNum,0,16); + qDebug(logUdp()) << this->metaObject()->className() << ": Sending (single packet) retransmit of " << QString("0x%1").arg(match->seqNum,0,16); match->retransmitCount++; udpMutex.lock(); udp->writeDatagram(match->data, radioIP, port); @@ -1302,7 +1302,7 @@ void udpBase::dataReceived(QByteArray r) else { // Found matching entry? // Send "untracked" as it has already been sent once. - qDebug(logUdp()) << this->metaObject()->className() << ": Remote has requested retransmit of " << QString("0x%1").arg(match->seqNum,0,16); + qDebug(logUdp()) << this->metaObject()->className() << ": Sending (multiple packet) retransmit of " << QString("0x%1").arg(match->seqNum,0,16); match->retransmitCount++; udpMutex.lock(); udp->writeDatagram(match->data, radioIP, port); @@ -1423,20 +1423,28 @@ void udpBase::sendRetransmitRequest() missingMutex.lock(); for (auto it = rxMissing.begin(); it != rxMissing.end(); ++it) { - if (it.value() < 10) - { - missingSeqs.append(it.key() & 0xff); - missingSeqs.append(it.key() >> 8 & 0xff); - missingSeqs.append(it.key() & 0xff); - missingSeqs.append(it.key() >> 8 & 0xff); - it.value()++; + if (&it.key() != Q_NULLPTR) { + if (it.value() < 4) + { + missingSeqs.append(it.key() & 0xff); + missingSeqs.append(it.key() >> 8 & 0xff); + missingSeqs.append(it.key() & 0xff); + missingSeqs.append(it.key() >> 8 & 0xff); + it.value()++; + } + else { + qInfo(logUdp()) << this->metaObject()->className() << ": No response for missing packet" << it.key() << "deleting"; + it = rxMissing.erase(it); + } } } missingMutex.unlock(); + if (missingSeqs.length() != 0) { control_packet p; memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00! + p.len = sizeof(p); p.type = 0x01; p.seq = 0x0000; p.sentid = myId; @@ -1453,7 +1461,8 @@ void udpBase::sendRetransmitRequest() { qInfo(logUdp()) << this->metaObject()->className() << ": sending request for multiple missing packets : " << missingSeqs.toHex(':'); missingMutex.lock(); - missingSeqs.insert(0, p.packet, sizeof(p.packet)); + p.len = sizeof(p)+missingSeqs.size(); + missingSeqs.insert(0, p.packet, sizeof(p)); missingMutex.unlock(); udpMutex.lock(); @@ -1506,24 +1515,6 @@ void udpBase::sendPing() return; } -void udpBase::sendRetransmitRange(quint16 first, quint16 second, quint16 third, quint16 fourth) -{ - retransmit_range_packet p; - memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00! - p.len = sizeof(p); - p.type = 0x00; - p.sentid = myId; - p.rcvdid = remoteId; - p.first = first; - p.second = second; - p.third = third; - p.fourth = fourth; - udpMutex.lock(); - udp->writeDatagram(QByteArray::fromRawData((const char*)p.packet, sizeof(p)), radioIP, port); - udpMutex.unlock(); - return; -} - void udpBase::sendTrackedPacket(QByteArray d) { diff --git a/udpserver.cpp b/udpserver.cpp index 6d6cb5c..d7c771e 100644 --- a/udpserver.cpp +++ b/udpserver.cpp @@ -796,17 +796,15 @@ void udpServer::commonReceived(QList* l, CLIENT* current, QByteArray r) if (current->idleTimer != Q_NULLPTR && !current->idleTimer->isActive()) { current->idleTimer->start(100); } - } // This is a retransmit request - else if (in->type == 0x01) + } // This is a single packet retransmit request + else if (in->type == 0x01 && in->len == 0x10) { - // Single packet request - qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Received 'retransmit' request for " << QString("0x%1").arg(in->seq,0,16); QMap::iterator match = current->txSeqBuf.find(in->seq); if (match != current->txSeqBuf.end() && match->retransmitCount < 5) { // Found matching entry? // Don't constantly retransmit the same packet, give-up eventually - qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Sending retransmit of " << QString("0x%1").arg(match->seqNum,0,16); + qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Sending (single packet) retransmit of " << QString("0x%1").arg(match->seqNum, 0, 16); match->retransmitCount++; if (udpMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) { @@ -820,6 +818,7 @@ void udpServer::commonReceived(QList* l, CLIENT* current, QByteArray r) } else { // Just send an idle! + qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Requested (single) packet " << QString("0x%1").arg(in->seq, 0, 16) << "not found"; sendControl(current, 0x00, in->seq); } } @@ -843,7 +842,7 @@ void udpServer::commonReceived(QList* l, CLIENT* current, QByteArray r) return s.seqNum == cs; }); if (match == current->txSeqBuf.end()) { - qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Requested packet " << QString("0x%1").arg(seq,0,16) << " not found"; + qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Requested (multiple) packet " << QString("0x%1").arg(seq,0,16) << " not found"; // Just send idle packet. sendControl(current, 0, in->seq); } @@ -851,7 +850,7 @@ void udpServer::commonReceived(QList* l, CLIENT* current, QByteArray r) { // Found matching entry? // Send "untracked" as it has already been sent once. - qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Sending retransmit of " << QString("0x%1").arg(match->seqNum,0,16); + qInfo(logUdpServer()) << current->ipAddress.toString() << "(" << current->type << "): Sending (multiple packet) retransmit of " << QString("0x%1").arg(match->seqNum,0,16); match->retransmitCount++; if (udpMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) { @@ -933,9 +932,9 @@ void udpServer::commonReceived(QList* l, CLIENT* current, QByteArray r) current->rxSeqBuf.insert(f, QTime::currentTime()); if (f != in->seq) { - qInfo(logUdpServer()) << "Detected missing packet" << f; if (!current->rxMissing.contains(f)) { + qInfo(logUdpServer()) << "Detected new missing packet" << f; current->rxMissing.insert(f, 0); } } @@ -1750,6 +1749,7 @@ void udpServer::sendRetransmitRequest(CLIENT* c) p.rcvdid = c->remoteId; if (missingSeqs.length() == 4) // This is just a single missing packet so send using a control. { + p.len = sizeof(p); p.seq = (missingSeqs[0] & 0xff) | (quint16)(missingSeqs[1] << 8); qInfo(logUdp()) << this->metaObject()->className() << ": sending request for missing packet : " << QString("0x%1").arg(p.seq,0,16); @@ -1767,7 +1767,8 @@ void udpServer::sendRetransmitRequest(CLIENT* c) { qInfo(logUdp()) << this->metaObject()->className() << ": sending request for multiple missing packets : " << missingSeqs.toHex(); - missingSeqs.insert(0, p.packet, sizeof(p.packet)); + p.len = sizeof(p) + missingSeqs.size(); + missingSeqs.insert(0, p.packet, sizeof(p)); if (udpMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) {