diff --git a/YSFControl.cpp b/YSFControl.cpp index 19f1d62..8468e7c 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -102,11 +102,15 @@ bool CYSFControl::writeModem(unsigned char *data) if (valid && fi == YSF_FI_TERMINATOR) { CSync::addYSFSync(data + 2U); + m_fich.encode(data + 2U); + unsigned char fn = m_fich.getFN(); unsigned char ft = m_fich.getFT(); unsigned char dt = m_fich.getDT(); - LogDebug("YSF, FI=%X FN=%u FT=%u DT=%X", fi, fn, ft, dt); + unsigned int errs = m_fich.getErrors(); + + LogDebug("YSF, FI=%X FN=%u FT=%u DT=%X Errs=%u", fi, fn, ft, dt, errs); // m_payload.process(data + 2U, fi, fn, ft, dt); @@ -142,12 +146,16 @@ bool CYSFControl::writeModem(unsigned char *data) CSync::addYSFSync(data + 2U); if (valid) { + m_fich.encode(data + 2U); + unsigned char cm = m_fich.getCM(); unsigned char fn = m_fich.getFN(); unsigned char ft = m_fich.getFT(); unsigned char dt = m_fich.getDT(); - LogDebug("YSF, FI=%X FN=%u FT=%u DT=%X", fi, fn, ft, dt); + unsigned int errs = m_fich.getErrors(); + + LogDebug("YSF, FI=%X FN=%u FT=%u DT=%X Errs=%u", fi, fn, ft, dt, errs); // m_payload.process(data + 2U, fi, fn, ft, dt); diff --git a/YSFFICH.cpp b/YSFFICH.cpp index 0b978cc..c14f29e 100644 --- a/YSFFICH.cpp +++ b/YSFFICH.cpp @@ -55,13 +55,17 @@ const unsigned int INTERLEAVE_TABLE[] = { 38U, 78U, 118U, 158U, 198U}; CYSFFICH::CYSFFICH() : -m_fich(NULL) +m_bytes(NULL), +m_fich(NULL), +m_errors(0U) { - m_fich = new unsigned char[6U]; + m_bytes = new unsigned char[YSF_FICH_LENGTH_BYTES]; + m_fich = new unsigned char[6U]; } CYSFFICH::~CYSFFICH() { + delete[] m_bytes; delete[] m_fich; } @@ -72,6 +76,9 @@ bool CYSFFICH::decode(const unsigned char* bytes) // Skip the sync bytes bytes += YSF_SYNC_LENGTH_BYTES; + // Save a copy of the FICH for later error rate calculations + ::memcpy(m_bytes, bytes, YSF_FICH_LENGTH_BYTES); + CYSFConvolution viterbi; viterbi.start(); @@ -157,6 +164,16 @@ void CYSFFICH::encode(unsigned char* bytes) n++; WRITE_BIT1(bytes, n, s1); } + + // Calculate the errors + m_errors = 0U; + for (unsigned int i = 0U; i < YSF_FICH_LENGTH_BYTES; i++) { + unsigned char v = bytes[i] ^ m_bytes[i]; + while (v != 0U) { + v &= v - 1U; + m_errors++; + } + } } unsigned char CYSFFICH::getFI() const @@ -203,3 +220,8 @@ void CYSFFICH::setVoIP(bool on) else m_fich[2U] &= 0xFBU; } + +unsigned int CYSFFICH::getErrors() const +{ + return m_errors; +} diff --git a/YSFFICH.h b/YSFFICH.h index 6e8cbe5..f308259 100644 --- a/YSFFICH.h +++ b/YSFFICH.h @@ -28,6 +28,8 @@ public: void encode(unsigned char* bytes); + unsigned int getErrors() const; + unsigned char getFI() const; unsigned char getCM() const; unsigned char getFN() const; @@ -39,7 +41,9 @@ public: void setVoIP(bool set); private: + unsigned char* m_bytes; unsigned char* m_fich; + unsigned int m_errors; }; #endif diff --git a/YSFPayload.cpp b/YSFPayload.cpp index d9357b6..c88ed79 100644 --- a/YSFPayload.cpp +++ b/YSFPayload.cpp @@ -96,7 +96,7 @@ void CYSFPayload::process(unsigned char* bytes, unsigned char fi, unsigned char assert(bytes != NULL); // Header and trailer - if (fi == 0U || fi == 2U) { + if (fi == YSF_FI_HEADER || fi == YSF_FI_TERMINATOR) { processHeader(bytes + YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES); return; } @@ -248,7 +248,7 @@ void CYSFPayload::processVDMode1(unsigned char* data, unsigned char fn) errors += m_fec.regenerateDMR(data + 63U); errors += m_fec.regenerateDMR(data + 81U); - LogMessage("YSF, V/D Mode 1, AMBE FEC %u/235 (%.1f%%)", errors, float(errors) / 235.0F); + LogMessage("YSF, V/D Mode 1, AMBE FEC %u/235 (%.1f%%)", errors, float(errors) / 2.35F); unsigned char dch[45U]; @@ -640,7 +640,7 @@ void CYSFPayload::processVoiceFRMode(unsigned char* data) errors += m_fec.regenerateYSF3(data + 54U); errors += m_fec.regenerateYSF3(data + 72U); - LogMessage("YSF, V Mode 3, AMBE FEC %u/720 (%.1f%%)", errors, float(errors) / 720.0F); + LogMessage("YSF, V Mode 3, AMBE FEC %u/720 (%.1f%%)", errors, float(errors) / 7.2F); } void CYSFPayload::setUplink(const std::string& callsign)