diff --git a/packettypes.h b/packettypes.h index ed2ec6c..703b2ca 100644 --- a/packettypes.h +++ b/packettypes.h @@ -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 diff --git a/udphandler.cpp b/udphandler.cpp index b1860f0..98a15a5 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -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(); } } diff --git a/udphandler.h b/udphandler.h index 60a0c7f..7d72d37 100644 --- a/udphandler.h +++ b/udphandler.h @@ -80,11 +80,12 @@ public: time_t timeSent; uint16_t seqNum; QByteArray data; + quint8 retransmitCount; }; - QVector txSeqBuf = QVector(); + QVector txSeqBuf; //= QVector(); - QVector< quint16 > rxSeqBuf = QVector(); + QVector rxSeqBuf; // = QVector(); void sendTrackedPacket(QByteArray d); void purgeOldEntries();