From 7ea832976186e580df7299b5f9e159123ca5bd48 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 13 Jun 2016 21:29:19 +0100 Subject: [PATCH] Fix sequence number bugs. --- YSFControl.cpp | 40 ++++++++++++++++++++-------------------- YSFControl.h | 2 +- YSFNetwork.cpp | 3 ++- YSFNetwork.h | 2 +- YSFPayload.cpp | 12 ++++++------ YSFPayload.h | 6 +++--- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/YSFControl.cpp b/YSFControl.cpp index dcfc50e..b556c54 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -111,8 +111,6 @@ bool CYSFControl::writeModem(unsigned char *data) // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); - m_rfFrames++; - valid = m_rfPayload.processHeaderData(data + 2U); if (valid) @@ -143,7 +141,7 @@ bool CYSFControl::writeModem(unsigned char *data) data[0U] = TAG_DATA; data[1U] = 0x00U; - writeNetwork(data); + writeNetwork(data, m_rfFrames % 128U); #if defined(DUMP_YSF) writeFile(data + 2U); @@ -154,19 +152,19 @@ bool CYSFControl::writeModem(unsigned char *data) fich.encode(data + 2U); writeQueueRF(data); } + + m_rfFrames++; } else if (valid && fi == YSF_FI_TERMINATOR) { CSync::addYSFSync(data + 2U); // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); - m_rfFrames++; - m_rfPayload.processHeaderData(data + 2U); data[0U] = TAG_EOT; data[1U] = 0x00U; - writeNetwork(data); + writeNetwork(data, m_rfFrames % 128U); #if defined(DUMP_YSF) writeFile(data + 2U); @@ -178,6 +176,8 @@ bool CYSFControl::writeModem(unsigned char *data) writeQueueRF(data); } + m_rfFrames++; + LogMessage("YSF, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); writeEndRF(); @@ -191,18 +191,16 @@ bool CYSFControl::writeModem(unsigned char *data) // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); - m_rfFrames++; - switch (dt) { case YSF_DT_VD_MODE1: valid = m_rfPayload.processVDMode1Data(data + 2U, fn); - m_rfErrs += m_rfPayload.processVDMode1Audio(data + 2U); + m_rfErrs += m_rfPayload.processVDMode1Audio(data + 2U, m_rfFrames % 128U); m_rfBits += 235U; break; case YSF_DT_VD_MODE2: valid = m_rfPayload.processVDMode2Data(data + 2U, fn); - m_rfErrs += m_rfPayload.processVDMode2Audio(data + 2U); + m_rfErrs += m_rfPayload.processVDMode2Audio(data + 2U, m_rfFrames % 128U); m_rfBits += 135U; break; @@ -213,7 +211,7 @@ bool CYSFControl::writeModem(unsigned char *data) case YSF_DT_VOICE_FR_MODE: if (fn != 0U || ft != 1U) { // The first packet after the header is odd, don't try and regenerate it - m_rfErrs += m_rfPayload.processVoiceFRModeAudio(data + 2U); + m_rfErrs += m_rfPayload.processVoiceFRModeAudio(data + 2U, m_rfFrames % 128U); m_rfBits += 720U; } valid = false; @@ -261,7 +259,7 @@ bool CYSFControl::writeModem(unsigned char *data) data[0U] = TAG_DATA; data[1U] = 0x00U; - writeNetwork(data); + writeNetwork(data, m_rfFrames % 128U); if (m_duplex) { fich.setMR(YSF_MR_BUSY); @@ -272,15 +270,15 @@ bool CYSFControl::writeModem(unsigned char *data) #if defined(DUMP_YSF) writeFile(data + 2U); #endif - } else { - CSync::addYSFSync(data + 2U); m_rfFrames++; + } else { + CSync::addYSFSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; - writeNetwork(data); + writeNetwork(data, m_rfFrames % 128U); if (m_duplex) writeQueueRF(data); @@ -288,6 +286,7 @@ bool CYSFControl::writeModem(unsigned char *data) #if defined(DUMP_YSF) writeFile(data + 2U); #endif + m_rfFrames++; } return true; @@ -405,6 +404,7 @@ void CYSFControl::writeNetwork() m_netFrames++; + unsigned char n = (data[34U] & 0xFEU) >> 1; bool end = (data[34U] & 0x01U) == 0x01U; data[33U] = end ? TAG_EOT : TAG_DATA; @@ -429,13 +429,13 @@ void CYSFControl::writeNetwork() switch (dt) { case YSF_DT_VD_MODE1: m_netPayload.processVDMode1Data(data + 35U, fn, gateway); - m_netErrs += m_netPayload.processVDMode1Audio(data + 35U); + m_netErrs += m_netPayload.processVDMode1Audio(data + 35U, n); m_netBits += 235U; break; case YSF_DT_VD_MODE2: m_netPayload.processVDMode2Data(data + 35U, fn, gateway); - m_netErrs += m_netPayload.processVDMode2Audio(data + 35U); + m_netErrs += m_netPayload.processVDMode2Audio(data + 35U, n); m_netBits += 135U; break; @@ -446,7 +446,7 @@ void CYSFControl::writeNetwork() case YSF_DT_VOICE_FR_MODE: if (fn != 0U || ft != 1U) { // The first packet after the header is odd, don't try and regenerate it - m_netErrs += m_netPayload.processVoiceFRModeAudio(data + 35U); + m_netErrs += m_netPayload.processVoiceFRModeAudio(data + 35U, n); m_netBits += 720U; } break; @@ -538,7 +538,7 @@ void CYSFControl::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CYSFControl::writeNetwork(const unsigned char *data) +void CYSFControl::writeNetwork(const unsigned char *data, unsigned int count) { assert(data != NULL); @@ -548,7 +548,7 @@ void CYSFControl::writeNetwork(const unsigned char *data) if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired()) return; - m_network->write(m_rfSource, m_rfDest, data + 2U, data[0U] == TAG_EOT); + m_network->write(m_rfSource, m_rfDest, data + 2U, count, data[0U] == TAG_EOT); } bool CYSFControl::openFile() diff --git a/YSFControl.h b/YSFControl.h index 89cb238..5acfe4b 100644 --- a/YSFControl.h +++ b/YSFControl.h @@ -68,7 +68,7 @@ private: void writeQueueRF(const unsigned char* data); void writeQueueNet(const unsigned char* data); - void writeNetwork(const unsigned char* data); + void writeNetwork(const unsigned char* data, unsigned int count); void writeNetwork(); void writeEndRF(); diff --git a/YSFNetwork.cpp b/YSFNetwork.cpp index 135e13f..2cb2e0d 100644 --- a/YSFNetwork.cpp +++ b/YSFNetwork.cpp @@ -65,7 +65,7 @@ bool CYSFNetwork::open() return m_socket.open(); } -bool CYSFNetwork::write(const unsigned char* src, const unsigned char* dest, const unsigned char* data, bool end) +bool CYSFNetwork::write(const unsigned char* src, const unsigned char* dest, const unsigned char* data, unsigned int count, bool end) { assert(data != NULL); @@ -90,6 +90,7 @@ bool CYSFNetwork::write(const unsigned char* src, const unsigned char* dest, con ::memset(buffer + 24U, ' ', YSF_CALLSIGN_LENGTH); buffer[34U] = end ? 0x01U : 0x00U; + buffer[34U] |= (count & 0x7FU) << 1; ::memcpy(buffer + 35U, data, YSF_FRAME_LENGTH_BYTES); diff --git a/YSFNetwork.h b/YSFNetwork.h index 409cd0a..f52887a 100644 --- a/YSFNetwork.h +++ b/YSFNetwork.h @@ -36,7 +36,7 @@ public: void enable(bool enabled); - bool write(const unsigned char* src, const unsigned char* dest, const unsigned char* data, bool end); + bool write(const unsigned char* src, const unsigned char* dest, const unsigned char* data, unsigned int count, bool end); unsigned int read(unsigned char* data); diff --git a/YSFPayload.cpp b/YSFPayload.cpp index 75a82e2..2aeddcb 100644 --- a/YSFPayload.cpp +++ b/YSFPayload.cpp @@ -249,7 +249,7 @@ bool CYSFPayload::processHeaderData(unsigned char* data) return valid1; } -unsigned int CYSFPayload::processVDMode1Audio(unsigned char* data) +unsigned int CYSFPayload::processVDMode1Audio(unsigned char* data, unsigned int count) { assert(data != NULL); @@ -263,7 +263,7 @@ unsigned int CYSFPayload::processVDMode1Audio(unsigned char* data) errors += m_fec.regenerateDMR(data + 63U); errors += m_fec.regenerateDMR(data + 81U); - LogDebug("YSF, V/D Mode 1, AMBE FEC %u/235 (%.1f%%)", errors, float(errors) / 2.35F); + LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", count, errors, float(errors) / 2.35F); return errors; } @@ -388,7 +388,7 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool return ret && (fn == 0U); } -unsigned int CYSFPayload::processVDMode2Audio(unsigned char* data) +unsigned int CYSFPayload::processVDMode2Audio(unsigned char* data, unsigned int count) { assert(data != NULL); @@ -441,7 +441,7 @@ unsigned int CYSFPayload::processVDMode2Audio(unsigned char* data) } } - LogDebug("YSF, V/D Mode 2, Repetition FEC %u/135 (%.1f%%)", errors, float(errors) / 1.35F); + LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", count, errors, float(errors) / 1.35F); // "errors" is the number of triplets that were recognized to be corrupted // and that were corrected. There are 27 of those per VCH and 5 VCH per CC, // yielding a total of 27*5 = 135. I believe the expected value of this @@ -873,7 +873,7 @@ bool CYSFPayload::processDataFRModeData(unsigned char* data, unsigned char fn, b return ret1 && (fn == 0U); } -unsigned int CYSFPayload::processVoiceFRModeAudio(unsigned char* data) +unsigned int CYSFPayload::processVoiceFRModeAudio(unsigned char* data, unsigned int count) { assert(data != NULL); @@ -887,7 +887,7 @@ unsigned int CYSFPayload::processVoiceFRModeAudio(unsigned char* data) errors += m_fec.regenerateYSF3(data + 54U); errors += m_fec.regenerateYSF3(data + 72U); - LogDebug("YSF, V Mode 3, AMBE FEC %u/720 (%.1f%%)", errors, float(errors) / 7.2F); + LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", count, errors, float(errors) / 7.2F); return errors; } diff --git a/YSFPayload.h b/YSFPayload.h index 8fc5061..1c076d6 100644 --- a/YSFPayload.h +++ b/YSFPayload.h @@ -31,14 +31,14 @@ public: bool processHeaderData(unsigned char* bytes); bool processVDMode1Data(unsigned char* bytes, unsigned char fn, bool gateway = false); - unsigned int processVDMode1Audio(unsigned char* bytes); + unsigned int processVDMode1Audio(unsigned char* bytes, unsigned int count); bool processVDMode2Data(unsigned char* bytes, unsigned char fn, bool gateway = false); - unsigned int processVDMode2Audio(unsigned char* bytes); + unsigned int processVDMode2Audio(unsigned char* bytes, unsigned int count); bool processDataFRModeData(unsigned char* bytes, unsigned char fn, bool gateway = false); - unsigned int processVoiceFRModeAudio(unsigned char* bytes); + unsigned int processVoiceFRModeAudio(unsigned char* bytes, unsigned int count); unsigned char* getSource(); unsigned char* getDest();