From 9e5664ccc570be61feb322f929915809874e7929 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 2 Feb 2016 19:54:51 +0000 Subject: [PATCH] Bug fixes to D-Star. --- DStarControl.cpp | 56 +++++++++++++++-------------------------------- DStarControl.h | 1 - DStarSlowData.cpp | 5 ++--- 3 files changed, 20 insertions(+), 42 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index fd02dc6..efb9d1a 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -90,15 +90,13 @@ bool CDStarControl::writeModem(unsigned char *data) return false; } - if (type == TAG_LOST && m_state != RS_RELAYING_NETWORK_AUDIO) { - m_state = RS_LISTENING; + if (type == TAG_LOST) { + if (m_state == RS_LATE_ENTRY) + m_state = RS_LISTENING; return false; } if (type == TAG_HEADER) { - if (m_state == RS_RELAYING_RF_AUDIO) - return false; - CDStarHeader header(data + 1U); // Is this a transmission destined for a repeater? @@ -127,8 +125,8 @@ bool CDStarControl::writeModem(unsigned char *data) m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0; if (m_state == RS_LISTENING) { - // Only reset the timeout if the ack is not pending - if (!m_ackTimer.isRunning()) { + // Only start the timeout if not already running + if (!m_timeoutTimer.isRunning()) { m_timeoutTimer.start(); m_bits = 1U; m_errs = 0U; @@ -209,8 +207,8 @@ bool CDStarControl::writeModem(unsigned char *data) return false; } else { if (m_state == RS_LISTENING) { - unsigned int bits = matchSync(data + 1U); - if (bits <= MAX_SYNC_BIT_ERRORS) { + // The sync is regenerated by the modem so can do exact match + if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) { m_slowData.start(); m_state = RS_LATE_ENTRY; } @@ -223,8 +221,8 @@ bool CDStarControl::writeModem(unsigned char *data) m_frames++; - unsigned int bits = matchSync(data + 1U); - if (bits <= MAX_SYNC_BIT_ERRORS) + // The sync is regenerated by the modem so can do exact match + if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) m_n = 0U; // Regenerate the sync @@ -248,8 +246,8 @@ bool CDStarControl::writeModem(unsigned char *data) return false; } else if (m_state == RS_LATE_ENTRY) { - unsigned int bits = matchSync(data + 1U); - if (bits <= MAX_SYNC_BIT_ERRORS) { + // The sync is regenerated by the modem so can do exact match + if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) { m_slowData.reset(); return false; } @@ -283,8 +281,8 @@ bool CDStarControl::writeModem(unsigned char *data) m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0; - // Only reset the timeout if the ack is not pending - if (!m_ackTimer.isRunning()) { + // Only reset the timeout if the timeout is not running + if (!m_timeoutTimer.isRunning()) { m_timeoutTimer.start(); m_bits = 1U; m_errs = 0U; @@ -399,7 +397,6 @@ void CDStarControl::writeNetwork() m_networkWatchdog.start(); unsigned char type = data[0U]; - unsigned char n = data[1U]; if (type == TAG_HEADER) { if (m_state != RS_LISTENING) @@ -430,8 +427,7 @@ void CDStarControl::writeNetwork() m_bits = 1U; m_errs = 0U; - data[1U] = TAG_HEADER; - writeQueueHeader(data + 1U); + writeQueueHeader(data); #if defined(DUMP_DSTAR) openFile(); @@ -466,6 +462,8 @@ void CDStarControl::writeNetwork() if (m_state != RS_RELAYING_NETWORK_AUDIO) return; + unsigned char n = data[1U]; + insertSilence(data + 2U, n); m_errs += m_fec.regenerateDStar(data + 2U); @@ -499,7 +497,6 @@ void CDStarControl::clock(unsigned int ms) m_ackTimer.clock(ms); if (m_ackTimer.isRunning() && m_ackTimer.hasExpired()) { sendAck(); - m_timeoutTimer.stop(); m_ackTimer.stop(); } @@ -704,27 +701,10 @@ void CDStarControl::blankDTMF(unsigned char* data) const ::memcpy(data, DSTAR_NULL_AMBE_DATA_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); } -unsigned int CDStarControl::matchSync(const unsigned char* data) const -{ - unsigned char bits[DSTAR_DATA_FRAME_LENGTH_BYTES]; - bits[0U] = data[9U] ^ DSTAR_SYNC_BYTES[0U]; - bits[1U] = data[10U] ^ DSTAR_SYNC_BYTES[1U]; - bits[2U] = data[11U] ^ DSTAR_SYNC_BYTES[2U]; - - unsigned int errors = 0U; - - for (unsigned int i = 0U; i < DSTAR_DATA_FRAME_LENGTH_BYTES; i++) { - while (bits[i] != 0x00U) { - bits[i] &= bits[i] - 1U; - errors++; - } - } - - return errors; -} - void CDStarControl::sendAck() { + m_timeoutTimer.stop(); + unsigned char user[DSTAR_LONG_CALLSIGN_LENGTH]; m_header.getMyCall1(user); diff --git a/DStarControl.h b/DStarControl.h index 32c3b12..5b0a97b 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -87,7 +87,6 @@ private: void insertSilence(unsigned int count); void blankDTMF(unsigned char* data) const; - unsigned int matchSync(const unsigned char* data) const; void sendAck(); }; diff --git a/DStarSlowData.cpp b/DStarSlowData.cpp index 013e512..e38ef6e 100644 --- a/DStarSlowData.cpp +++ b/DStarSlowData.cpp @@ -89,9 +89,8 @@ CDStarHeader* CDStarSlowData::add(const unsigned char* data) CCRC::addCCITT16(m_header, DSTAR_HEADER_LENGTH_BYTES); // Compare them - if (crc[0U] != m_header[39U] || crc[1U] != m_header[40U]) { - m_header[39U] = 0x00U; - m_header[40U] = 0x00U; + if (::memcmp(crc, m_header + 39U, 2U) != 0) { + ::memcpy(m_header + 39U, crc, 2U); return NULL; }