kopia lustrzana https://gitlab.com/eliggett/wfview
More fixes to retransmit logic
rodzic
84d558c08c
commit
80148a84bf
|
@ -35,6 +35,21 @@ typedef union control_packet {
|
||||||
} *control_packet_t;
|
} *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
|
// 0x15 length ping packet
|
||||||
// Also used for the slightly different civ header packet.
|
// Also used for the slightly different civ header packet.
|
||||||
typedef union ping_packet {
|
typedef union ping_packet {
|
||||||
|
@ -167,13 +182,14 @@ typedef union status_packet {
|
||||||
char unusede; // 0x28
|
char unusede; // 0x28
|
||||||
char unusedf[2]; // 0x29
|
char unusedf[2]; // 0x29
|
||||||
char value[5]; // 0x2b
|
char value[5]; // 0x2b
|
||||||
quint32 error; // 0x30
|
quint32 error; // 0x30
|
||||||
char unusedg[12]; // 0x34
|
char unusedg[12]; // 0x34
|
||||||
char disc; // 0x40
|
char disc; // 0x40
|
||||||
char unusedh; // 0x41
|
char unusedh; // 0x41
|
||||||
quint32 civport; // 0x42 // Sent bigendian
|
quint16 civport; // 0x42 // Sent bigendian
|
||||||
quint32 audioport; // 0x46 // Sent bigendian
|
quint16 unusedi; // 0x44 // Sent bigendian
|
||||||
char unusedi[5]; // 0x4a
|
quint16 audioport; // 0x46 // Sent bigendian
|
||||||
|
char unusedj[7]; // 0x49
|
||||||
};
|
};
|
||||||
char packet[STATUS_SIZE];
|
char packet[STATUS_SIZE];
|
||||||
} *status_packet_t;
|
} *status_packet_t;
|
||||||
|
@ -247,7 +263,7 @@ typedef union conninfo_packet {
|
||||||
quint32 token; // 0x1c
|
quint32 token; // 0x1c
|
||||||
quint16 authstartid; // 0x20
|
quint16 authstartid; // 0x20
|
||||||
char unusedd[5]; // 0x22
|
char unusedd[5]; // 0x22
|
||||||
quint32 resb; // 0x27
|
quint32 commoncap; // 0x27
|
||||||
char identa; // 0x2b
|
char identa; // 0x2b
|
||||||
quint32 identb; // 0x2c
|
quint32 identb; // 0x2c
|
||||||
char unusedf[16]; // 0x30
|
char unusedf[16]; // 0x30
|
||||||
|
@ -298,7 +314,7 @@ typedef union capabilities_packet {
|
||||||
char unusedd[33]; // 0x20
|
char unusedd[33]; // 0x20
|
||||||
char capa; // 0x41
|
char capa; // 0x41
|
||||||
char unusede[7]; // 0x42
|
char unusede[7]; // 0x42
|
||||||
quint16 capb; // 0x49
|
quint16 commoncap; // 0x49
|
||||||
char unusedf[2]; // 0x4b
|
char unusedf[2]; // 0x4b
|
||||||
char capc; // 0x4d
|
char capc; // 0x4d
|
||||||
quint32 capd; // 0x4e
|
quint32 capd; // 0x4e
|
||||||
|
|
|
@ -343,7 +343,7 @@ void udpHandler::sendRequestStream()
|
||||||
p.rcvdid = remoteId;
|
p.rcvdid = remoteId;
|
||||||
p.code = 0x0180;
|
p.code = 0x0180;
|
||||||
p.res = 0x03;
|
p.res = 0x03;
|
||||||
p.resb = 0x8010;
|
p.commoncap = 0x8010;
|
||||||
p.identa = identa;
|
p.identa = identa;
|
||||||
p.identb = identb;
|
p.identb = identb;
|
||||||
p.innerseq = authInnerSendSeq;
|
p.innerseq = authInnerSendSeq;
|
||||||
|
@ -803,16 +803,23 @@ void udpBase::dataReceived(QByteArray r)
|
||||||
// Send an idle with the requested seqnum if not found.
|
// Send an idle with the requested seqnum if not found.
|
||||||
packetsLost++;
|
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;
|
return s.seqNum == cs;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (match != txSeqBuf.cend()) {
|
if (match != txSeqBuf.end()) {
|
||||||
// Found matching entry?
|
// Found matching entry?
|
||||||
// Send "untracked" as it has already been sent once.
|
// Send "untracked" as it has already been sent once.
|
||||||
QMutexLocker locker(&mutex);
|
// Don't constantly retransmit the same packet, give-up eventually
|
||||||
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
|
if (match->retransmitCount < 4) {
|
||||||
udp->writeDatagram(match->data, radioIP, port);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -869,24 +876,27 @@ void udpBase::dataReceived(QByteArray r)
|
||||||
{ // retransmit range request
|
{ // retransmit range request
|
||||||
qDebug() << this->metaObject()->className() << ": Retransmit range request for:" << in->first << ", " << in->second << ", " << in->third << ", " << in->fourth << ", ";
|
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;
|
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.";
|
qDebug() << this->metaObject()->className() << ": Could not find requested packet " << in->seq << ", sending idle.";
|
||||||
sendControl(false, 0, in->seq);
|
sendControl(false, 0, in->seq);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (match != txSeqBuf.cend()) {
|
while (match != txSeqBuf.end()) {
|
||||||
// Found matching entry?
|
// Found matching entry?
|
||||||
// Send "untracked" as it has already been sent once.
|
// Send "untracked" as it has already been sent once.
|
||||||
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
|
if (match->retransmitCount <4) {
|
||||||
QMutexLocker locker(&mutex);
|
qDebug() << this->metaObject()->className() << ": Sending retransmit of " << match->seqNum;
|
||||||
udp->writeDatagram(match->data, radioIP, port);
|
QMutexLocker locker(&mutex);
|
||||||
udp->writeDatagram(match->data, radioIP, port);
|
udp->writeDatagram(match->data, radioIP, port);
|
||||||
match++;
|
udp->writeDatagram(match->data, radioIP, port);
|
||||||
packetsLost++;
|
match->retransmitCount++;
|
||||||
|
match++;
|
||||||
|
packetsLost++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -940,16 +950,23 @@ void udpBase::dataReceived(QByteArray r)
|
||||||
second = *i;
|
second = *i;
|
||||||
else if (count == 2)
|
else if (count == 2)
|
||||||
third = *i;
|
third = *i;
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
count++;
|
count++;
|
||||||
i++;
|
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;
|
qDebug() << this->metaObject()->className() << ": Requesting retransmit of: " << first;
|
||||||
|
rxSeqBuf.append(first);
|
||||||
sendControl(false, 0x01, first);
|
sendControl(false, 0x01, first);
|
||||||
}
|
}
|
||||||
else if (count == 2) {
|
else if (count == 2) {
|
||||||
|
@ -960,6 +977,10 @@ void udpBase::dataReceived(QByteArray r)
|
||||||
if (count == 3)
|
if (count == 3)
|
||||||
{
|
{
|
||||||
qDebug() << this->metaObject()->className() << ": Requesting retransmit of: " << first << ", " << second << ", " << third;
|
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);
|
sendRetransmitRange(first, second, third);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1057,10 +1078,12 @@ void udpBase::purgeOldEntries()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rxSeqBuf.length() > 2048) {
|
if (rxSeqBuf.length() > 2048) {
|
||||||
|
|
||||||
// If the buffer is over 2K, remove the first 1K.
|
// If the buffer is over 2K, remove the first 1K.
|
||||||
std::sort(rxSeqBuf.begin(), rxSeqBuf.end());
|
std::sort(rxSeqBuf.begin(), rxSeqBuf.end());
|
||||||
rxSeqBuf.remove(0,1024);
|
rxSeqBuf.remove(0,1024);
|
||||||
lastReceivedSeq = *rxSeqBuf.begin();
|
lastReceivedSeq = *rxSeqBuf.begin();
|
||||||
|
qDebug() << this->metaObject()->className() << ": Purged buffer of old rx packets, new buffer: " << rxSeqBuf.first() << " - " << rxSeqBuf.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,11 +80,12 @@ public:
|
||||||
time_t timeSent;
|
time_t timeSent;
|
||||||
uint16_t seqNum;
|
uint16_t seqNum;
|
||||||
QByteArray data;
|
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 sendTrackedPacket(QByteArray d);
|
||||||
void purgeOldEntries();
|
void purgeOldEntries();
|
||||||
|
|
Ładowanie…
Reference in New Issue