More fixes to retransmit logic

merge-requests/2/head
Phil Taylor 2021-02-23 20:48:53 +00:00
rodzic 84d558c08c
commit 80148a84bf
3 zmienionych plików z 67 dodań i 27 usunięć

Wyświetl plik

@ -35,6 +35,21 @@ typedef union control_packet {
} *control_packet_t;
// 0x14 length watchdog packet
typedef union watchdog_packet {
struct {
quint32 len; // 0x00
quint16 type; // 0x04
quint16 seq; // 0x06
quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c
quint16 secondsa; // 0x10
quint16 secondsb; // 0x12
};
char packet[WATCHDOG_SIZE];
} *watchdog_packet_t;
// 0x15 length ping packet
// Also used for the slightly different civ header packet.
typedef union ping_packet {
@ -167,13 +182,14 @@ typedef union status_packet {
char unusede; // 0x28
char unusedf[2]; // 0x29
char value[5]; // 0x2b
quint32 error; // 0x30
quint32 error; // 0x30
char unusedg[12]; // 0x34
char disc; // 0x40
char unusedh; // 0x41
quint32 civport; // 0x42 // Sent bigendian
quint32 audioport; // 0x46 // Sent bigendian
char unusedi[5]; // 0x4a
quint16 civport; // 0x42 // Sent bigendian
quint16 unusedi; // 0x44 // Sent bigendian
quint16 audioport; // 0x46 // Sent bigendian
char unusedj[7]; // 0x49
};
char packet[STATUS_SIZE];
} *status_packet_t;
@ -247,7 +263,7 @@ typedef union conninfo_packet {
quint32 token; // 0x1c
quint16 authstartid; // 0x20
char unusedd[5]; // 0x22
quint32 resb; // 0x27
quint32 commoncap; // 0x27
char identa; // 0x2b
quint32 identb; // 0x2c
char unusedf[16]; // 0x30
@ -298,7 +314,7 @@ typedef union capabilities_packet {
char unusedd[33]; // 0x20
char capa; // 0x41
char unusede[7]; // 0x42
quint16 capb; // 0x49
quint16 commoncap; // 0x49
char unusedf[2]; // 0x4b
char capc; // 0x4d
quint32 capd; // 0x4e

Wyświetl plik

@ -343,7 +343,7 @@ void udpHandler::sendRequestStream()
p.rcvdid = remoteId;
p.code = 0x0180;
p.res = 0x03;
p.resb = 0x8010;
p.commoncap = 0x8010;
p.identa = identa;
p.identb = identb;
p.innerseq = authInnerSendSeq;
@ -803,16 +803,23 @@ void udpBase::dataReceived(QByteArray r)
// Send an idle with the requested seqnum if not found.
packetsLost++;
auto match = std::find_if(txSeqBuf.cbegin(), txSeqBuf.cend(), [&cs = in->seq](const SEQBUFENTRY& s) {
auto match = std::find_if(txSeqBuf.begin(), txSeqBuf.end(), [&cs = in->seq](SEQBUFENTRY& s) {
return s.seqNum == cs;
});
if (match != txSeqBuf.cend()) {
if (match != txSeqBuf.end()) {
// Found matching entry?
// Send "untracked" as it has already been sent once.
QMutexLocker locker(&mutex);
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
udp->writeDatagram(match->data, radioIP, port);
// Don't constantly retransmit the same packet, give-up eventually
if (match->retransmitCount < 4) {
QMutexLocker locker(&mutex);
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
match->retransmitCount++;
udp->writeDatagram(match->data, radioIP, port);
}
else {
sendControl(false, 0, in->seq);
}
break;
}
else {
@ -869,24 +876,27 @@ void udpBase::dataReceived(QByteArray r)
{ // retransmit range request
qDebug() << this->metaObject()->className() << ": Retransmit range request for:" << in->first << ", " << in->second << ", " << in->third << ", " << in->fourth << ", ";
auto match = std::find_if(txSeqBuf.cbegin(), txSeqBuf.cend(), [&ca = in->first, &cb = in->second, &cc = in->third, &cd = in->fourth](const SEQBUFENTRY& s) {
auto match = std::find_if(txSeqBuf.begin(), txSeqBuf.end(), [&ca = in->first, &cb = in->second, &cc = in->third, &cd = in->fourth](SEQBUFENTRY& s) {
return s.seqNum == ca || s.seqNum == cb || s.seqNum == cc || s.seqNum == cd;
});
if (match == txSeqBuf.cend()) {
if (match == txSeqBuf.end()) {
qDebug() << this->metaObject()->className() << ": Could not find requested packet " << in->seq << ", sending idle.";
sendControl(false, 0, in->seq);
}
else {
while (match != txSeqBuf.cend()) {
while (match != txSeqBuf.end()) {
// Found matching entry?
// Send "untracked" as it has already been sent once.
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
QMutexLocker locker(&mutex);
udp->writeDatagram(match->data, radioIP, port);
udp->writeDatagram(match->data, radioIP, port);
match++;
packetsLost++;
if (match->retransmitCount <4) {
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
QMutexLocker locker(&mutex);
udp->writeDatagram(match->data, radioIP, port);
udp->writeDatagram(match->data, radioIP, port);
match->retransmitCount++;
match++;
packetsLost++;
}
}
}
}
@ -940,16 +950,23 @@ void udpBase::dataReceived(QByteArray r)
second = *i;
else if (count == 2)
third = *i;
else {
break;
}
count++;
i++;
}
if (count == 1)
if (count > 6) // Something bad happened, clear the buffer.
{
qDebug() << this->metaObject()->className() << ": Excessive lost incoming packets, clearing buffer: " << count << " packets lost!";
rxSeqBuf.clear();
rxSeqBuf.append(in->seq);
lastReceivedSeq = in->seq;
}
else if (count == 1)
{
qDebug() << this->metaObject()->className() << ": Requesting retransmit of: " << first;
rxSeqBuf.append(first);
sendControl(false, 0x01, first);
}
else if (count == 2) {
@ -960,6 +977,10 @@ void udpBase::dataReceived(QByteArray r)
if (count == 3)
{
qDebug() << this->metaObject()->className() << ": Requesting retransmit of: " << first << ", " << second << ", " << third;
rxSeqBuf.append(first);
rxSeqBuf.append(second);
if (second != third)
rxSeqBuf.append(third);
sendRetransmitRange(first, second, third);
}
}
@ -1057,10 +1078,12 @@ void udpBase::purgeOldEntries()
}
if (rxSeqBuf.length() > 2048) {
// If the buffer is over 2K, remove the first 1K.
std::sort(rxSeqBuf.begin(), rxSeqBuf.end());
rxSeqBuf.remove(0,1024);
lastReceivedSeq = *rxSeqBuf.begin();
qDebug() << this->metaObject()->className() << ": Purged buffer of old rx packets, new buffer: " << rxSeqBuf.first() << " - " << rxSeqBuf.last();
}
}

Wyświetl plik

@ -80,11 +80,12 @@ public:
time_t timeSent;
uint16_t seqNum;
QByteArray data;
quint8 retransmitCount;
};
QVector<SEQBUFENTRY> txSeqBuf = QVector<SEQBUFENTRY>();
QVector<SEQBUFENTRY> txSeqBuf; //= QVector<SEQBUFENTRY>();
QVector< quint16 > rxSeqBuf = QVector<quint16>();
QVector<quint16> rxSeqBuf; // = QVector<quint16>();
void sendTrackedPacket(QByteArray d);
void purgeOldEntries();