From 351c1199fbfe810b2569f0df4c40dee4ef5d3b7e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 27 Feb 2025 12:46:25 +0000 Subject: [PATCH] Remove the D-Star fast data handling for now as it appears to be mangling D-Star DTMF data. --- AMBEFEC.cpp | 22 ++--- DStarControl.cpp | 219 +++++++++++++---------------------------------- DStarControl.h | 23 +---- Version.h | 4 +- 4 files changed, 75 insertions(+), 193 deletions(-) diff --git a/AMBEFEC.cpp b/AMBEFEC.cpp index 03f8ac2..3e141ed 100644 --- a/AMBEFEC.cpp +++ b/AMBEFEC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2014,2016,2018,2021 by Jonathan Naylor G4KLX + * Copyright (C) 2010,2014,2016,2018,2021,2025 by Jonathan Naylor G4KLX * Copyright (C) 2016 Mathias Weyland, HB9FRV * * This program is free software; you can redistribute it and/or modify @@ -798,8 +798,6 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const unsigned int data; bool valid1 = CGolay24128::decode24128(a, data); - if (!valid1) - return 10U; // The PRNG unsigned int p = PRNG_TABLE[data]; @@ -808,14 +806,15 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const unsigned int datb; bool valid2 = CGolay24128::decode24128(b, datb); - if (!valid2) - return 10U; a = CGolay24128::encode24128(data); b = CGolay24128::encode24128(datb); b ^= p; + if (!valid1 || !valid2) + return 10U; + unsigned int v = a ^ orig_a; unsigned int errsA = CUtils::countBits(v); @@ -832,12 +831,6 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned unsigned int data; bool valid = CGolay24128::decode24128(a, data); - if (!valid) { - a = 0xF00292U; - b = 0x0E0B20U; - c = 0x000000U; - return 10U; // An invalid A block gives an error count of 10 - } a = CGolay24128::encode24128(data); @@ -852,6 +845,13 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned b ^= p; + if (!valid) { + a = 0xF00292U; + b = 0x0E0B20U; + c = 0x000000U; + return 10U; // An invalid A block gives an error count of 10 + } + unsigned int v = a ^ orig_a; unsigned int errsA = CUtils::countBits(v); diff --git a/DStarControl.cpp b/DStarControl.cpp index c0d727a..d6a42ac 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2019,2021,2023 Jonathan Naylor, G4KLX + * Copyright (C) 2015-2019,2021,2023,2025 Jonathan Naylor, G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,6 @@ #include const unsigned int MAX_SYNC_BIT_ERRORS = 2U; -const unsigned int FAST_DATA_BEEP_GRACE_FRAMES = 6U; bool CallsignCompare(const std::string& arg, const unsigned char* my) { @@ -86,15 +85,7 @@ m_minRSSI(0U), m_aveRSSI(0U), m_rssiCount(0U), m_enabled(true), -m_fp(NULL), -m_rfVoiceSyncData(NULL), -m_rfVoiceSyncDataLen(0U), -m_netVoiceSyncData(NULL), -m_netVoiceSyncDataLen(0U), -m_rfNextFrameIsFastData(false), -m_netNextFrameIsFastData(false), -m_rfSkipDTMFBlankingFrames(0U), -m_netSkipDTMFBlankingFrames(0U) +m_fp(NULL) { assert(display != NULL); assert(rssiMapper != NULL); @@ -103,8 +94,6 @@ m_netSkipDTMFBlankingFrames(0U) m_gateway = new unsigned char[DSTAR_LONG_CALLSIGN_LENGTH]; m_lastFrame = new unsigned char[DSTAR_FRAME_LENGTH_BYTES + 1U]; - m_rfVoiceSyncData = new unsigned char[DSTAR_MODEM_DATA_LEN]; - m_netVoiceSyncData = new unsigned char[DSTAR_MODEM_DATA_LEN]; std::string call = callsign; call.resize(DSTAR_LONG_CALLSIGN_LENGTH - 1U, ' '); @@ -129,84 +118,6 @@ CDStarControl::~CDStarControl() delete[] m_callsign; delete[] m_gateway; delete[] m_lastFrame; - delete[] m_rfVoiceSyncData; - delete[] m_netVoiceSyncData; -} - -unsigned int CDStarControl::maybeFixupVoiceFrame( - unsigned char* data, - unsigned int len, - unsigned int offset, - const char* log_prefix, - unsigned char n, - bool blank_dtmf, - unsigned char* voice_sync_data, - unsigned int& voice_sync_data_len, - bool& next_frame_is_fast_data, - unsigned int& skip_dtmf_blanking_frames - ) -{ - unsigned int errors = 0U; - unsigned int voice_sync_errors = 0U; - unsigned char mini_header = data[offset + 9U] ^ DSTAR_SCRAMBLER_BYTES[0U]; - unsigned char mini_header_type = mini_header & DSTAR_SLOW_DATA_TYPE_MASK; - - if (n == 0U) { - ::memcpy(voice_sync_data, data, DSTAR_MODEM_DATA_LEN); - voice_sync_data_len = len; - } else if ((n % 2U != 0U) && - ((mini_header_type == DSTAR_SLOW_DATA_TYPE_FASTDATA01) || - (mini_header_type == DSTAR_SLOW_DATA_TYPE_FASTDATA16))) { - next_frame_is_fast_data = true; - if (blank_dtmf) - skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; - if (n == 1U) - LogDebug("D-Star, %s fastdata sequence no. 0", log_prefix); - LogDebug("D-Star, %s fastdata sequence no. %2u", log_prefix, n); - } else if (next_frame_is_fast_data) { - next_frame_is_fast_data = false; - if (blank_dtmf) - skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; - LogDebug("D-Star, %s fastdata sequence no. %2u", log_prefix, n); - } else { - bool voice_sync_data_is_null_ambe_data = false; - bool data_is_null_ambe_data = false; - - if ((n == 1U) && (::memcmp(voice_sync_data + offset, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0)) - voice_sync_data_is_null_ambe_data = true; - - if (::memcmp(data + offset, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0) - data_is_null_ambe_data = true; - - if ((n == 1U) && !voice_sync_data_is_null_ambe_data) - voice_sync_errors += m_fec.regenerateDStar(voice_sync_data + offset); - - if (!data_is_null_ambe_data) - errors += m_fec.regenerateDStar(data + offset); - - if (blank_dtmf && skip_dtmf_blanking_frames > 0U) { - skip_dtmf_blanking_frames--; - } else if (blank_dtmf && skip_dtmf_blanking_frames == 0U) { - if ((n == 1U) && !voice_sync_data_is_null_ambe_data) - blankDTMF(voice_sync_data + offset); - if (!data_is_null_ambe_data) - blankDTMF(data + offset); - } - - if (n == 1U) { - if (voice_sync_data_is_null_ambe_data) - LogDebug("D-Star, %s nullaudio sequence no. 0", log_prefix); - else - LogDebug("D-Star, %s audio sequence no. 0, errs: %2u/48 (%5.1f%%)", log_prefix, voice_sync_errors, float(voice_sync_errors) / 0.48F); - } - - if (data_is_null_ambe_data) - LogDebug("D-Star, %s nullaudio sequence no. %2u", log_prefix, n); - else - LogDebug("D-Star, %s audio sequence no. %2u, errs: %2u/48 (%5.1f%%)", log_prefix, n, errors, float(errors) / 0.48F); - } - - return voice_sync_errors + errors; } bool CDStarControl::writeModem(unsigned char *data, unsigned int len) @@ -416,9 +327,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (m_duplex) writeQueueEOTRF(); - m_rfNextFrameIsFastData = false; - m_rfSkipDTMFBlankingFrames = 0U; - unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH]; @@ -436,11 +344,13 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) return false; } else if (type == TAG_DATA) { - if (m_rfState == RS_RF_REJECTED) { + if (m_rfState == RS_RF_REJECTED) return true; - } else if (m_rfState == RS_RF_INVALID) { + + if (m_rfState == RS_RF_INVALID) return true; - } else if (m_rfState == RS_RF_LISTENING) { + + if (m_rfState == RS_RF_LISTENING) { // 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_rfSlowData.start(); @@ -448,7 +358,9 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } return false; - } else if (m_rfState == RS_RF_AUDIO) { + } + + if (m_rfState == RS_RF_AUDIO) { // 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_rfSlowData.start(); @@ -463,7 +375,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) unsigned int errors = 0U; if (!m_rfHeader.isDataPacket()) { - errors = maybeFixupVoiceFrame(data, len, 1U, "RF", m_rfN, m_duplex, m_rfVoiceSyncData, m_rfVoiceSyncDataLen, m_rfNextFrameIsFastData, m_rfSkipDTMFBlankingFrames); + errors = m_fec.regenerateDStar(data + 1U); m_display->writeDStarBER(float(errors) / 0.48F); m_rfErrs += errors; } @@ -471,22 +383,18 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_rfBits += 48U; m_rfFrames++; - const unsigned char* text = m_rfSlowData.addText(data + 1U); - if (text != NULL) - LogMessage("D-Star, slow data text = \"%s\"", text); - - if (m_net) { - if (m_rfN == 1U) - writeNetworkDataRF(m_rfVoiceSyncData, 0U, false); - if (m_rfN >= 1U) - writeNetworkDataRF(data, errors, false); + if (m_rfN != 0U) { + const unsigned char* text = m_rfSlowData.addText(data + 1U); + if (text != NULL) + LogMessage("D-Star, RF slow data text = \"%s\"", text); } + if (m_net) + writeNetworkDataRF(data, errors, false); + if (m_duplex) { - if (m_rfN == 1U) - writeQueueDataRF(m_rfVoiceSyncData); - if (m_rfN >= 1U) - writeQueueDataRF(data); + blankDTMF(data + 1U); + writeQueueDataRF(data); } m_rfN = (m_rfN + 1U) % 21U; @@ -495,58 +403,55 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) { m_rfSlowData.reset(); return false; + } else { + CDStarHeader* header = m_rfSlowData.addHeader(data + 1U); + if (header == NULL) + return false; + + m_rfHeader = *header; + delete header; } - CDStarHeader* header = m_rfSlowData.addHeader(data + 1U); - if (header == NULL) - return false; - - m_rfHeader = *header; - unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; - header->getMyCall1(my1); + m_rfHeader.getMyCall1(my1); // Is this a transmission destined for a repeater? - if (!header->isRepeater()) { + if (!m_rfHeader.isRepeater()) { LogMessage("D-Star, non repeater RF header received from %8.8s", my1); m_rfState = RS_RF_INVALID; - delete header; return true; } unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH]; - header->getRPTCall1(callsign); + m_rfHeader.getRPTCall1(callsign); // Is it for us? if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) { LogMessage("D-Star, received RF header for wrong repeater (%8.8s) from %8.8s", callsign, my1); m_rfState = RS_RF_INVALID; - delete header; return true; } if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0 && !(std::find_if(m_whiteList.begin(), m_whiteList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_whiteList.end())) { LogMessage("D-Star, invalid access attempt from %8.8s", my1); m_rfState = RS_RF_REJECTED; - delete header; return true; } if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) { LogMessage("D-Star, invalid access attempt from %8.8s", my1); m_rfState = RS_RF_REJECTED; - delete header; return true; } unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH]; - header->getRPTCall2(gateway); + m_rfHeader.getRPTCall2(gateway); unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; - header->getMyCall2(my2); + m_rfHeader.getMyCall2(my2); unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH]; - header->getYourCall(your); + m_rfHeader.getYourCall(your); m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0; @@ -574,10 +479,11 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) start[0U] = TAG_HEADER; // Modify the header - header->setRepeater(false); - header->setRPTCall1(m_callsign); - header->setRPTCall2(m_callsign); - header->get(start + 1U); + CDStarHeader header(m_rfHeader); + header.setRepeater(false); + header.setRPTCall1(m_callsign); + header.setRPTCall2(m_callsign); + header.get(start + 1U); writeQueueHeaderRF(start); } @@ -587,19 +493,19 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) start[0U] = TAG_HEADER; // Modify the header - header->setRepeater(false); - header->setRPTCall1(m_callsign); - header->setRPTCall2(m_gateway); - header->get(start + 1U); + CDStarHeader header(m_rfHeader); + header.setRepeater(false); + header.setRPTCall1(m_callsign); + header.setRPTCall2(m_gateway); + header.get(start + 1U); writeNetworkHeaderRF(start); } - delete header; - unsigned int errors = 0U; if (!m_rfHeader.isDataPacket()) { - errors = maybeFixupVoiceFrame(data, len, 1U, "RF", m_rfN, m_duplex, m_rfVoiceSyncData, m_rfVoiceSyncDataLen, m_rfNextFrameIsFastData, m_rfSkipDTMFBlankingFrames); + errors = m_fec.regenerateDStar(data + 1U); + LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); m_rfErrs += errors; } @@ -608,8 +514,10 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (m_net) writeNetworkDataRF(data, errors, false); - if (m_duplex) + if (m_duplex) { + blankDTMF(data + 1U); writeQueueDataRF(data); + } m_rfState = RS_RF_AUDIO; @@ -774,9 +682,6 @@ void CDStarControl::writeNetwork() writeFile(data + 1U, length - 1U); closeFile(); #endif - m_netNextFrameIsFastData = false; - m_netSkipDTMFBlankingFrames = 0U; - unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH]; @@ -793,13 +698,15 @@ void CDStarControl::writeNetwork() if (m_netState != RS_NET_AUDIO) return; + unsigned int errors = 0U; unsigned char n = data[1U]; - data[1U] = TAG_DATA; - - unsigned int errors = 0U; if (!m_netHeader.isDataPacket()) - errors = maybeFixupVoiceFrame(data, length, 2U, "Net", n, true, m_netVoiceSyncData, m_netVoiceSyncDataLen, m_netNextFrameIsFastData, m_netSkipDTMFBlankingFrames); + errors = m_fec.regenerateDStar(data + 2U); + + blankDTMF(data + 2U); + + data[1U] = TAG_DATA; // Insert silence and reject if in the past bool ret = insertSilence(data + 1U, n); @@ -817,23 +724,19 @@ void CDStarControl::writeNetwork() m_netSlowData.start(); } - const unsigned char* text = m_netSlowData.addText(data + 2U); - if (text != NULL) - LogMessage("D-Star, slow data text = \"%s\"", text); + if (n != 0U) { + const unsigned char* text = m_netSlowData.addText(data + 2U); + if (text != NULL) + LogMessage("D-Star, network slow data text = \"%s\"", text); + } m_packetTimer.start(); m_netFrames++; #if defined(DUMP_DSTAR) - if (n == 1U) - writeFile(m_netVoiceSyncData + 1U, m_netVoiceSyncDataLen - 1U); - if (n >= 1U) - writeFile(data + 1U, length - 1U); + writeFile(data + 1U, length - 1U); #endif - if (n == 1U) - writeQueueDataNet(m_netVoiceSyncData + 1U); - if (n >= 1U) - writeQueueDataNet(data + 1U); + writeQueueDataNet(data + 1U); } else { CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U); } diff --git a/DStarControl.h b/DStarControl.h index 61bf03f..35dbcda 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2019 by Jonathan Naylor G4KLX + * Copyright (C) 2015-2019,2025 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -99,27 +99,6 @@ private: unsigned int m_rssiCount; bool m_enabled; FILE* m_fp; - unsigned char* m_rfVoiceSyncData; - unsigned int m_rfVoiceSyncDataLen; - unsigned char* m_netVoiceSyncData; - unsigned int m_netVoiceSyncDataLen; - bool m_rfNextFrameIsFastData; - bool m_netNextFrameIsFastData; - unsigned int m_rfSkipDTMFBlankingFrames; - unsigned int m_netSkipDTMFBlankingFrames; - - unsigned int maybeFixupVoiceFrame( - unsigned char* data, - unsigned int len, - unsigned int offset, - const char* log_prefix, - unsigned char n, - bool blank_dtmf, - unsigned char* voice_sync_data, - unsigned int& voice_sync_data_len, - bool& next_frame_is_fast_data, - unsigned int& skip_dtmf_blanking_frames - ); void writeNetwork(); diff --git a/Version.h b/Version.h index fcb4eb5..7fac374 100644 --- a/Version.h +++ b/Version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2024 by Jonathan Naylor G4KLX + * Copyright (C) 2015-2025 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20240930"; +const char* VERSION = "20250227"; #endif