From da92771afa25121beb7a109688a70c8ba5c0184d Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:13:37 -0500 Subject: [PATCH 01/19] Revert "Remove more redundant code." This reverts commit c3c5fe1a5a783b0d2ab5c93750aaaace4bbb9cb6. --- DStarDefines.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DStarDefines.h b/DStarDefines.h index d979041..9db014c 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2018,2019 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2018 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 @@ -67,6 +67,8 @@ const unsigned char DSTAR_ACK_FLAG = 0x03U; const unsigned char DSTAR_NO_RESPONSE = 0x02U; const unsigned char DSTAR_RELAY_UNAVAILABLE = 0x01U; +const unsigned char DSTAR_FAST_DATA_GUARD_BYTE = 0x02U; + const unsigned char DSTAR_SYNC_BYTES[] = {0x55U, 0x2DU, 0x16U}; const unsigned char DSTAR_DTMF_MASK[] = { 0x82U, 0x08U, 0x20U, 0x82U, 0x00U, 0x00U, 0x82U, 0x00U, 0x00U }; From 59b8b5d6234a71a4e01146ac56e56dd91d476e4e Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:13:57 -0500 Subject: [PATCH 02/19] Revert "Remove redundant code." This reverts commit f88c9826a734e5d5c60140c20197078f7d9eb2e5. --- DStarControl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 6c5b6cf..add4b24 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -359,7 +359,8 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) // Check for the fast data signature if (m_rfState == RS_RF_AUDIO && (m_rfN % 2U) == 1U) { unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTES[0U]) & DSTAR_SLOW_DATA_TYPE_MASK; - if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { + unsigned char guard = data[4U + 1U] ^ DSTAR_SCRAMBLER_BYTES[4U]; + if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) /* && guard == DSTAR_FAST_DATA_GUARD_BYTE */) { LogMessage("D-Star, switching to fast data mode"); m_rfState = RS_RF_DATA; } @@ -735,7 +736,8 @@ void CDStarControl::writeNetwork() // Check for the fast data signature if (m_netState == RS_NET_AUDIO && (n % 2U) == 1U) { unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] ^ DSTAR_SCRAMBLER_BYTES[0U]) & DSTAR_SLOW_DATA_TYPE_MASK; - if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { + unsigned char guard = data[4U + 2U] ^ DSTAR_SCRAMBLER_BYTES[4U]; + if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) /* && guard == DSTAR_FAST_DATA_GUARD_BYTE */) { LogMessage("D-Star, switching to fast data mode"); m_netState = RS_NET_DATA; } From a87449bf51fdeb2ce35b467a4b2120b12663f92f Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:14:10 -0500 Subject: [PATCH 03/19] Revert "Loosen fast data admission criteria." This reverts commit 6d719353c6fb9fc05b83ec6aba97469dcbe25215. --- DStarControl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index add4b24..f7f568d 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -360,7 +360,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (m_rfState == RS_RF_AUDIO && (m_rfN % 2U) == 1U) { unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTES[0U]) & DSTAR_SLOW_DATA_TYPE_MASK; unsigned char guard = data[4U + 1U] ^ DSTAR_SCRAMBLER_BYTES[4U]; - if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) /* && guard == DSTAR_FAST_DATA_GUARD_BYTE */) { + if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) && guard == DSTAR_FAST_DATA_GUARD_BYTE) { LogMessage("D-Star, switching to fast data mode"); m_rfState = RS_RF_DATA; } @@ -737,7 +737,7 @@ void CDStarControl::writeNetwork() if (m_netState == RS_NET_AUDIO && (n % 2U) == 1U) { unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] ^ DSTAR_SCRAMBLER_BYTES[0U]) & DSTAR_SLOW_DATA_TYPE_MASK; unsigned char guard = data[4U + 2U] ^ DSTAR_SCRAMBLER_BYTES[4U]; - if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) /* && guard == DSTAR_FAST_DATA_GUARD_BYTE */) { + if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) && guard == DSTAR_FAST_DATA_GUARD_BYTE) { LogMessage("D-Star, switching to fast data mode"); m_netState = RS_NET_DATA; } From c94f4f5d4ac3d4d9374615d9141e3e1cbc1d3afd Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:14:31 -0500 Subject: [PATCH 04/19] Revert "Check the guard byte on fast data as well as the mini header." This reverts commit 317bda01770ef28f3ed6117af898b7628bffa545. --- DStarControl.cpp | 10 ++++------ DStarDefines.h | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index f7f568d..7cf3f74 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -358,9 +358,8 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) // Check for the fast data signature if (m_rfState == RS_RF_AUDIO && (m_rfN % 2U) == 1U) { - unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTES[0U]) & DSTAR_SLOW_DATA_TYPE_MASK; - unsigned char guard = data[4U + 1U] ^ DSTAR_SCRAMBLER_BYTES[4U]; - if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) && guard == DSTAR_FAST_DATA_GUARD_BYTE) { + unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTE1) & DSTAR_SLOW_DATA_TYPE_MASK; + if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { LogMessage("D-Star, switching to fast data mode"); m_rfState = RS_RF_DATA; } @@ -735,9 +734,8 @@ void CDStarControl::writeNetwork() // Check for the fast data signature if (m_netState == RS_NET_AUDIO && (n % 2U) == 1U) { - unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] ^ DSTAR_SCRAMBLER_BYTES[0U]) & DSTAR_SLOW_DATA_TYPE_MASK; - unsigned char guard = data[4U + 2U] ^ DSTAR_SCRAMBLER_BYTES[4U]; - if ((slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) && guard == DSTAR_FAST_DATA_GUARD_BYTE) { + unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] & DSTAR_SLOW_DATA_TYPE_MASK; + if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { LogMessage("D-Star, switching to fast data mode"); m_netState = RS_NET_DATA; } diff --git a/DStarDefines.h b/DStarDefines.h index 9db014c..3f826ac 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -53,7 +53,7 @@ const unsigned char DSTAR_SLOW_DATA_TYPE_FAST_DATA2 = 0x90U; const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U; const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU; -const unsigned char DSTAR_SCRAMBLER_BYTES[] = { 0x70U, 0x4FU, 0x93U, 0x40U, 0x64U, 0x74U, 0x6DU, 0x30U, 0x2BU }; +const unsigned char DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U}; const unsigned char DSTAR_DATA_MASK = 0x80U; const unsigned char DSTAR_REPEATER_MASK = 0x40U; @@ -67,7 +67,9 @@ const unsigned char DSTAR_ACK_FLAG = 0x03U; const unsigned char DSTAR_NO_RESPONSE = 0x02U; const unsigned char DSTAR_RELAY_UNAVAILABLE = 0x01U; -const unsigned char DSTAR_FAST_DATA_GUARD_BYTE = 0x02U; +const unsigned char DSTAR_SCRAMBLER_BYTE1 = 0x70U; +const unsigned char DSTAR_SCRAMBLER_BYTE2 = 0x4FU; +const unsigned char DSTAR_SCRAMBLER_BYTE3 = 0x93U; const unsigned char DSTAR_SYNC_BYTES[] = {0x55U, 0x2DU, 0x16U}; From 7ea37fc5e9b6dd3b669ea34db745a085fecb2b91 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:44:33 -0500 Subject: [PATCH 05/19] Revert "Fix the silence insertion for D-Star." This reverts commit 9cc2bfaaec4af1aac38b7cb243be61a72674ce56. --- DStarControl.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 7cf3f74..67817aa 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -730,10 +730,10 @@ void CDStarControl::writeNetwork() writeEndNet(); } } else if (type == TAG_DATA) { - unsigned char n = data[1U]; + unsigned char m_netN = data[1U]; // Check for the fast data signature - if (m_netState == RS_NET_AUDIO && (n % 2U) == 1U) { + if (m_netState == RS_NET_AUDIO && (m_netN % 2U) == 1U) { unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] & DSTAR_SLOW_DATA_TYPE_MASK; if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { LogMessage("D-Star, switching to fast data mode"); @@ -749,8 +749,6 @@ void CDStarControl::writeNetwork() m_netBits += 72U; m_netErrs = 0U; - m_netN = n; - // Regenerate the sync if (m_netN == 0U) CSync::addDStarSync(data + 2U); @@ -780,15 +778,13 @@ void CDStarControl::writeNetwork() data[1U] = TAG_DATA; // Insert silence and reject if in the past - bool ret = insertSilence(data + 1U, n); + bool ret = insertSilence(data + 1U, m_netN); if (!ret) return; m_netErrs += errors; m_netBits += 48U; - m_netN = n; - // Regenerate the sync if (m_netN == 0U) CSync::addDStarSync(data + 2U); From bbbfbbbfad3eff26b0280884f10a06ea8cb32d73 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:45:19 -0500 Subject: [PATCH 06/19] Revert "Simplify the D-Star sequence number processing." This reverts commit 99d4a9bc51382baa52bb52ee32d7f40e454843b3. --- DStarControl.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 67817aa..d65b93e 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -730,8 +730,6 @@ void CDStarControl::writeNetwork() writeEndNet(); } } else if (type == TAG_DATA) { - unsigned char m_netN = data[1U]; - // Check for the fast data signature if (m_netState == RS_NET_AUDIO && (m_netN % 2U) == 1U) { unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] & DSTAR_SLOW_DATA_TYPE_MASK; @@ -744,13 +742,17 @@ void CDStarControl::writeNetwork() } if (m_netState == RS_NET_DATA) { + unsigned char n = data[1U]; + data[1U] = TAG_DATA; m_netBits += 72U; m_netErrs = 0U; + m_netN = n; + // Regenerate the sync - if (m_netN == 0U) + if (n == 0U) CSync::addDStarSync(data + 2U); m_packetTimer.start(); @@ -760,9 +762,12 @@ void CDStarControl::writeNetwork() writeFile(data + 1U, length - 1U); #endif writeQueueDataNet(data + 1U); - } else if (m_netState == RS_NET_AUDIO) { - unsigned int errors = 0U; + m_netN = (m_netN + 1U) % 21U; + } else if (m_netState == RS_NET_AUDIO) { + unsigned char n = data[1U]; + + unsigned int errors = 0U; if (!m_netHeader.isDataPacket()) { if (CUtils::compare(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { // Fix any scrambled null data frames, typically sent by Kenwood D-Star radios @@ -778,15 +783,17 @@ void CDStarControl::writeNetwork() data[1U] = TAG_DATA; // Insert silence and reject if in the past - bool ret = insertSilence(data + 1U, m_netN); + bool ret = insertSilence(data + 1U, n); if (!ret) return; m_netErrs += errors; m_netBits += 48U; + m_netN = n; + // Regenerate the sync - if (m_netN == 0U) + if (n == 0U) CSync::addDStarSync(data + 2U); m_packetTimer.start(); @@ -796,6 +803,8 @@ void CDStarControl::writeNetwork() writeFile(data + 1U, length - 1U); #endif writeQueueDataNet(data + 1U); + + m_netN = (m_netN + 1U) % 21U; } } else { CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U); From fcad5ee0d29109fd4be0a1666c99bde1e2658378 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:46:19 -0500 Subject: [PATCH 07/19] Revert "Only test the slow data type in the correct place." This reverts commit ff0082b18bd4e6424361039657b65abc4c121307. --- DStarControl.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index d65b93e..40f1f89 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -357,14 +357,12 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } // Check for the fast data signature - if (m_rfState == RS_RF_AUDIO && (m_rfN % 2U) == 1U) { + if (m_rfState == RS_RF_AUDIO) { unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTE1) & DSTAR_SLOW_DATA_TYPE_MASK; if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { LogMessage("D-Star, switching to fast data mode"); m_rfState = RS_RF_DATA; } - } else { - // Handle return to voice mode here? } if (m_rfState == RS_RF_DATA) { @@ -731,14 +729,12 @@ void CDStarControl::writeNetwork() } } else if (type == TAG_DATA) { // Check for the fast data signature - if (m_netState == RS_NET_AUDIO && (m_netN % 2U) == 1U) { + if (m_netState == RS_NET_AUDIO) { unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] & DSTAR_SLOW_DATA_TYPE_MASK; if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { LogMessage("D-Star, switching to fast data mode"); m_netState = RS_NET_DATA; } - } else { - // Handle return to voice mode here? } if (m_netState == RS_NET_DATA) { @@ -762,8 +758,6 @@ void CDStarControl::writeNetwork() writeFile(data + 1U, length - 1U); #endif writeQueueDataNet(data + 1U); - - m_netN = (m_netN + 1U) % 21U; } else if (m_netState == RS_NET_AUDIO) { unsigned char n = data[1U]; @@ -803,8 +797,6 @@ void CDStarControl::writeNetwork() writeFile(data + 1U, length - 1U); #endif writeQueueDataNet(data + 1U); - - m_netN = (m_netN + 1U) % 21U; } } else { CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U); From 449ca905ee51639fa3b39a71ff0969b643964eca Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:47:04 -0500 Subject: [PATCH 08/19] Revert "Place the scrambled null data regeneration into the right place." This reverts commit 59cb07329d9479ce07d16ea9ef93184e57669475. --- DStarControl.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 40f1f89..68fbb13 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -356,6 +356,10 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) return false; } + // Fix any scrambled null data frames + if (CUtils::compare(data + 1U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 1U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); + // Check for the fast data signature if (m_rfState == RS_RF_AUDIO) { unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTE1) & DSTAR_SLOW_DATA_TYPE_MASK; @@ -390,14 +394,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } else if (m_rfState == RS_RF_AUDIO) { unsigned int errors = 0U; if (!m_rfHeader.isDataPacket()) { - if (CUtils::compare(data + 1U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - // Fix any scrambled null data frames, typically sent by Kenwood D-Star radios - ::memcpy(data + 1U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); - } else { - // This appears to be a normal FEC protected audio frame - errors = m_fec.regenerateDStar(data + 1U); - } - + errors = m_fec.regenerateDStar(data + 1U); m_display->writeDStarBER(float(errors) / 0.48F); LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); m_rfErrs += errors; @@ -728,6 +725,10 @@ void CDStarControl::writeNetwork() writeEndNet(); } } else if (type == TAG_DATA) { + // Fix any scrambled null data frames + if (CUtils::compare(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); + // Check for the fast data signature if (m_netState == RS_NET_AUDIO) { unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] & DSTAR_SLOW_DATA_TYPE_MASK; @@ -762,15 +763,8 @@ void CDStarControl::writeNetwork() unsigned char n = data[1U]; unsigned int errors = 0U; - if (!m_netHeader.isDataPacket()) { - if (CUtils::compare(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - // Fix any scrambled null data frames, typically sent by Kenwood D-Star radios - ::memcpy(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); - } else { - // This appears to be a normal FEC protected audio frame - errors = m_fec.regenerateDStar(data + 2U); - } - } + if (!m_netHeader.isDataPacket()) + errors = m_fec.regenerateDStar(data + 2U); blankDTMF(data + 2U); From 2d2b736c54f1c4c8a74f32a0148b3e24c1c328ce Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:47:24 -0500 Subject: [PATCH 09/19] Revert "Don't forget to descramble the byte first." This reverts commit 16bf9d574535b232e8e635f9cf0def2fab8ca9e6. --- DStarControl.cpp | 2 +- DStarDefines.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 68fbb13..18d161a 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -362,7 +362,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) // Check for the fast data signature if (m_rfState == RS_RF_AUDIO) { - unsigned char slowDataType = (data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] ^ DSTAR_SCRAMBLER_BYTE1) & DSTAR_SLOW_DATA_TYPE_MASK; + unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] & DSTAR_SLOW_DATA_TYPE_MASK; if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { LogMessage("D-Star, switching to fast data mode"); m_rfState = RS_RF_DATA; diff --git a/DStarDefines.h b/DStarDefines.h index 3f826ac..821a7e2 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -67,10 +67,6 @@ const unsigned char DSTAR_ACK_FLAG = 0x03U; const unsigned char DSTAR_NO_RESPONSE = 0x02U; const unsigned char DSTAR_RELAY_UNAVAILABLE = 0x01U; -const unsigned char DSTAR_SCRAMBLER_BYTE1 = 0x70U; -const unsigned char DSTAR_SCRAMBLER_BYTE2 = 0x4FU; -const unsigned char DSTAR_SCRAMBLER_BYTE3 = 0x93U; - const unsigned char DSTAR_SYNC_BYTES[] = {0x55U, 0x2DU, 0x16U}; const unsigned char DSTAR_DTMF_MASK[] = { 0x82U, 0x08U, 0x20U, 0x82U, 0x00U, 0x00U, 0x82U, 0x00U, 0x00U }; From b8ae0febb04172b2e74476c1d513140fa105f78d Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:47:51 -0500 Subject: [PATCH 10/19] Revert "New way to detect D-Star fast data mode." This reverts commit a9b7179d13319c1ec7ea66208269cb0c98e30289. --- DStarControl.cpp | 58 +++++++++++++++++++++++++++++++++--------------- DStarDefines.h | 18 +++++++-------- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 18d161a..99bd759 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -356,20 +356,31 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) return false; } - // Fix any scrambled null data frames - if (CUtils::compare(data + 1U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 1U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); - - // Check for the fast data signature - if (m_rfState == RS_RF_AUDIO) { - unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 1U] & DSTAR_SLOW_DATA_TYPE_MASK; - if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { - LogMessage("D-Star, switching to fast data mode"); + // Data signatures only appear at the beginning of the frame + if (m_rfState == RS_RF_AUDIO && m_rfFrames < 21U) { + if (CUtils::compare(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + LogMessage("D-Star, switching to data mode (Kenwood)"); + m_rfState = RS_RF_DATA; + } else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + LogMessage("D-Star, switching to data mode (Icom)"); + m_rfState = RS_RF_DATA; + } else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + LogMessage("D-Star, switching to data mode (Icom)"); m_rfState = RS_RF_DATA; } } if (m_rfState == RS_RF_DATA) { + // Regenerate the data mode markers + if (m_rfFrames < 21U) { + if (CUtils::compare(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); + else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES); + else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES); + } + m_rfBits += 72U; m_rfErrs = 0U; m_rfFrames++; @@ -725,20 +736,31 @@ void CDStarControl::writeNetwork() writeEndNet(); } } else if (type == TAG_DATA) { - // Fix any scrambled null data frames - if (CUtils::compare(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 2U, DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); - - // Check for the fast data signature - if (m_netState == RS_NET_AUDIO) { - unsigned char slowDataType = data[DSTAR_VOICE_FRAME_LENGTH_BYTES + 2U] & DSTAR_SLOW_DATA_TYPE_MASK; - if (slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA1 || slowDataType == DSTAR_SLOW_DATA_TYPE_FAST_DATA2) { - LogMessage("D-Star, switching to fast data mode"); + // Data signatures only appear at the beginning of the frame + if (m_netState == RS_NET_AUDIO && m_netFrames < 21U) { + if (CUtils::compare(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + LogMessage("D-Star, switching to data mode (Kenwood)"); + m_netState = RS_NET_DATA; + } else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + LogMessage("D-Star, switching to data mode (Icom)"); + m_netState = RS_NET_DATA; + } else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + LogMessage("D-Star, switching to data mode (Icom)"); m_netState = RS_NET_DATA; } } if (m_netState == RS_NET_DATA) { + // Regenerate the data mode markers + if (m_netFrames < 21U) { + if (CUtils::compare(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); + else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES); + else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) + ::memcpy(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES); + } + unsigned char n = data[1U]; data[1U] = TAG_DATA; diff --git a/DStarDefines.h b/DStarDefines.h index 821a7e2..697f57a 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -36,7 +36,9 @@ const unsigned char DSTAR_NULL_SLOW_DATA_BYTES[] = { 0x16, 0x29, 0xF5 }; const unsigned char DSTAR_NULL_FRAME_SYNC_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16 }; const unsigned char DSTAR_NULL_FRAME_DATA_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xF5 }; -const unsigned char DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES[] = { 0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U }; +const unsigned char DSTAR_KENWOOD_DATA_MODE_BYTES[] = { 0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U }; +const unsigned char DSTAR_ICOM_DATA_MODE_BYTES1[] = { 0xB2U, 0x4DU, 0x22U, 0x48U, 0xC0U, 0x16U, 0x28U, 0x26U, 0xC8U }; +const unsigned char DSTAR_ICOM_DATA_MODE_BYTES2[] = { 0x70U, 0x4FU, 0x93U, 0x40U, 0x64U, 0x74U, 0x6DU, 0x30U, 0x2BU }; const unsigned int DSTAR_VOICE_FRAME_LENGTH_BYTES = 9U; const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U; @@ -44,14 +46,12 @@ const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U; const unsigned int DSTAR_LONG_CALLSIGN_LENGTH = 8U; const unsigned int DSTAR_SHORT_CALLSIGN_LENGTH = 4U; -const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U; -const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U; -const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U; -const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U; -const unsigned char DSTAR_SLOW_DATA_TYPE_FAST_DATA1 = 0x80U; -const unsigned char DSTAR_SLOW_DATA_TYPE_FAST_DATA2 = 0x90U; -const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U; -const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU; +const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U; +const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U; +const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U; +const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U; +const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U; +const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU; const unsigned char DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U}; From 4f0f0fea66ac92aaa609aad70992936f5753ee57 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:50:47 -0500 Subject: [PATCH 11/19] Revert "Don't insert silence on lost D-Star fast data." This reverts commit 1bd814a07910c053c813afcbcd6a34a0a15d5e39. --- DStarControl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 99bd759..12e41fd 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -856,8 +856,7 @@ void CDStarControl::clock() } } - // Only insert silence on audio data - if (m_netState == RS_NET_AUDIO) { + if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) { m_packetTimer.clock(ms); if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) { From 821db7910a36cd0fad0a8a5b9a937a881b7ce0ac Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:51:06 -0500 Subject: [PATCH 12/19] Revert "Regenerate the data mode markers." This reverts commit 54fbacb4878059679740f4b0eda71f09ecf988b2. --- DStarControl.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 12e41fd..9687716 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -371,16 +371,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } if (m_rfState == RS_RF_DATA) { - // Regenerate the data mode markers - if (m_rfFrames < 21U) { - if (CUtils::compare(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); - else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES); - else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES); - } - m_rfBits += 72U; m_rfErrs = 0U; m_rfFrames++; @@ -751,16 +741,6 @@ void CDStarControl::writeNetwork() } if (m_netState == RS_NET_DATA) { - // Regenerate the data mode markers - if (m_netFrames < 21U) { - if (CUtils::compare(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES); - else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES); - else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) - ::memcpy(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES); - } - unsigned char n = data[1U]; data[1U] = TAG_DATA; From 7aabb96351dc8b9c217bf3632fd201e8fbf727d5 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 17:51:22 -0500 Subject: [PATCH 13/19] Revert "Fix a bug and add a second Icom D-Star fast data mode identifier." This reverts commit 18398efe976f16fca76de38786a6849ac0197c74. --- DStarControl.cpp | 14 ++++---------- DStarDefines.h | 5 ++--- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 9687716..dbb4ea5 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -361,10 +361,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (CUtils::compare(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { LogMessage("D-Star, switching to data mode (Kenwood)"); m_rfState = RS_RF_DATA; - } else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - LogMessage("D-Star, switching to data mode (Icom)"); - m_rfState = RS_RF_DATA; - } else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + } else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { LogMessage("D-Star, switching to data mode (Icom)"); m_rfState = RS_RF_DATA; } @@ -730,13 +727,10 @@ void CDStarControl::writeNetwork() if (m_netState == RS_NET_AUDIO && m_netFrames < 21U) { if (CUtils::compare(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { LogMessage("D-Star, switching to data mode (Kenwood)"); - m_netState = RS_NET_DATA; - } else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES1, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { + m_rfState = RS_RF_DATA; + } else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { LogMessage("D-Star, switching to data mode (Icom)"); - m_netState = RS_NET_DATA; - } else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES2, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - LogMessage("D-Star, switching to data mode (Icom)"); - m_netState = RS_NET_DATA; + m_rfState = RS_RF_DATA; } } diff --git a/DStarDefines.h b/DStarDefines.h index 697f57a..0e32e29 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016 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 @@ -37,8 +37,7 @@ const unsigned char DSTAR_NULL_FRAME_SYNC_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32 const unsigned char DSTAR_NULL_FRAME_DATA_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xF5 }; const unsigned char DSTAR_KENWOOD_DATA_MODE_BYTES[] = { 0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U }; -const unsigned char DSTAR_ICOM_DATA_MODE_BYTES1[] = { 0xB2U, 0x4DU, 0x22U, 0x48U, 0xC0U, 0x16U, 0x28U, 0x26U, 0xC8U }; -const unsigned char DSTAR_ICOM_DATA_MODE_BYTES2[] = { 0x70U, 0x4FU, 0x93U, 0x40U, 0x64U, 0x74U, 0x6DU, 0x30U, 0x2BU }; +const unsigned char DSTAR_ICOM_DATA_MODE_BYTES[] = { 0xB2U, 0x4DU, 0x22U, 0x48U, 0xC0U, 0x16U, 0x28U, 0x26U, 0xC8U }; const unsigned int DSTAR_VOICE_FRAME_LENGTH_BYTES = 9U; const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U; From 1fd1a4f6d11a17d12476f056760cf706c473ddbc Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 18:01:02 -0500 Subject: [PATCH 14/19] Revert "First attempt at detecting D-Star data frames, Kenwood and Icom." This reverts commit 3362e29b629b27a639185da5eb9d1b7cdfbfa382. --- DStarControl.cpp | 171 ++++++++++++++--------------------------------- DStarDefines.h | 3 - Utils.cpp | 19 ------ Utils.h | 2 - 4 files changed, 50 insertions(+), 145 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index dbb4ea5..b553097 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -127,7 +127,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) unsigned char type = data[0U]; - if (type == TAG_LOST && (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA)) { + if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) { unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH]; @@ -316,7 +316,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } return false; - } else if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) { + } else if (m_rfState == RS_RF_AUDIO) { if (m_net) writeNetworkDataRF(DSTAR_END_PATTERN_BYTES, 0U, true); @@ -340,13 +340,11 @@ 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 false; - - if (m_rfState == RS_RF_INVALID) + } else if (m_rfState == RS_RF_INVALID) { return false; - - if (m_rfState == RS_RF_LISTENING) { + } else 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_slowData.start(); @@ -354,41 +352,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } return false; - } - - // Data signatures only appear at the beginning of the frame - if (m_rfState == RS_RF_AUDIO && m_rfFrames < 21U) { - if (CUtils::compare(data + 1U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - LogMessage("D-Star, switching to data mode (Kenwood)"); - m_rfState = RS_RF_DATA; - } else if (CUtils::compare(data + 1U, DSTAR_ICOM_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - LogMessage("D-Star, switching to data mode (Icom)"); - m_rfState = RS_RF_DATA; - } - } - - if (m_rfState == RS_RF_DATA) { - m_rfBits += 72U; - m_rfErrs = 0U; - m_rfFrames++; - - // 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_rfN = 0U; - - // Regenerate the sync and send the RSSI data to the display - if (m_rfN == 0U) { - CSync::addDStarSync(data + 1U); - m_display->writeDStarRSSI(m_rssi); - } - - if (m_net) - writeNetworkDataRF(data, 0U, false); - - if (m_duplex) - writeQueueDataRF(data); - - m_rfN = (m_rfN + 1U) % 21U; } else if (m_rfState == RS_RF_AUDIO) { unsigned int errors = 0U; if (!m_rfHeader.isDataPacket()) { @@ -396,10 +359,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_display->writeDStarBER(float(errors) / 0.48F); LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); m_rfErrs += 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_rfN = 0U; } m_rfBits += 48U; @@ -630,7 +589,7 @@ void CDStarControl::writeNetwork() if (!m_enabled) return; - if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) && m_netState == RS_NET_IDLE) + if (m_rfState == RS_RF_AUDIO && m_netState == RS_NET_IDLE) return; m_networkWatchdog.start(); @@ -700,94 +659,64 @@ void CDStarControl::writeNetwork() m_elapsed.start(); } else if (type == TAG_EOT) { - if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) { - writeQueueEOTNet(); + if (m_netState != RS_NET_AUDIO) + return; - data[1U] = TAG_EOT; + writeQueueEOTNet(); + + data[1U] = TAG_EOT; #if defined(DUMP_DSTAR) - writeFile(data + 1U, length - 1U); - closeFile(); + writeFile(data + 1U, length - 1U); + closeFile(); #endif - unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; - unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; - unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH]; - m_netHeader.getMyCall1(my1); - m_netHeader.getMyCall2(my2); - m_netHeader.getYourCall(your); + unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; + unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; + unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH]; + m_netHeader.getMyCall1(my1); + m_netHeader.getMyCall2(my2); + m_netHeader.getYourCall(your); - // We've received the header and EOT haven't we? - m_netFrames += 2U; - LogMessage("D-Star, received network end of transmission from %8.8s/%4.4s to %8.8s, %.1f seconds, %u%% packet loss, BER: %.1f%%", my1, my2, your, float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits)); + // We've received the header and EOT haven't we? + m_netFrames += 2U; + LogMessage("D-Star, received network end of transmission from %8.8s/%4.4s to %8.8s, %.1f seconds, %u%% packet loss, BER: %.1f%%", my1, my2, your, float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits)); - writeEndNet(); - } + writeEndNet(); } else if (type == TAG_DATA) { - // Data signatures only appear at the beginning of the frame - if (m_netState == RS_NET_AUDIO && m_netFrames < 21U) { - if (CUtils::compare(data + 2U, DSTAR_KENWOOD_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - LogMessage("D-Star, switching to data mode (Kenwood)"); - m_rfState = RS_RF_DATA; - } else if (CUtils::compare(data + 2U, DSTAR_ICOM_DATA_MODE_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES) < 5U) { - LogMessage("D-Star, switching to data mode (Icom)"); - m_rfState = RS_RF_DATA; - } - } + if (m_netState != RS_NET_AUDIO) + return; - if (m_netState == RS_NET_DATA) { - unsigned char n = data[1U]; + unsigned char n = data[1U]; - data[1U] = TAG_DATA; + unsigned int errors = 0U; + if (!m_netHeader.isDataPacket()) + errors = m_fec.regenerateDStar(data + 2U); - m_netBits += 72U; - m_netErrs = 0U; + blankDTMF(data + 2U); - m_netN = n; + data[1U] = TAG_DATA; - // Regenerate the sync - if (n == 0U) - CSync::addDStarSync(data + 2U); + // Insert silence and reject if in the past + bool ret = insertSilence(data + 1U, n); + if (!ret) + return; - m_packetTimer.start(); - m_netFrames++; + m_netErrs += errors; + m_netBits += 48U; + + m_netN = n; + + // Regenerate the sync + if (n == 0U) + CSync::addDStarSync(data + 2U); + + m_packetTimer.start(); + m_netFrames++; #if defined(DUMP_DSTAR) - writeFile(data + 1U, length - 1U); + writeFile(data + 1U, length - 1U); #endif - writeQueueDataNet(data + 1U); - } else if (m_netState == RS_NET_AUDIO) { - unsigned char n = data[1U]; - - unsigned int errors = 0U; - if (!m_netHeader.isDataPacket()) - 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); - if (!ret) - return; - - m_netErrs += errors; - m_netBits += 48U; - - m_netN = n; - - // Regenerate the sync - if (n == 0U) - CSync::addDStarSync(data + 2U); - - m_packetTimer.start(); - m_netFrames++; - -#if defined(DUMP_DSTAR) - writeFile(data + 1U, length - 1U); -#endif - writeQueueDataNet(data + 1U); - } + writeQueueDataNet(data + 1U); } else { CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U); } @@ -816,7 +745,7 @@ void CDStarControl::clock() m_rfTimeoutTimer.clock(ms); m_netTimeoutTimer.clock(ms); - if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) { + if (m_netState == RS_NET_AUDIO) { m_networkWatchdog.clock(ms); if (m_networkWatchdog.hasExpired()) { @@ -830,7 +759,7 @@ void CDStarControl::clock() } } - if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) { + if (m_netState == RS_NET_AUDIO) { m_packetTimer.clock(ms); if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) { diff --git a/DStarDefines.h b/DStarDefines.h index 0e32e29..498b35e 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -36,9 +36,6 @@ const unsigned char DSTAR_NULL_SLOW_DATA_BYTES[] = { 0x16, 0x29, 0xF5 }; const unsigned char DSTAR_NULL_FRAME_SYNC_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16 }; const unsigned char DSTAR_NULL_FRAME_DATA_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xF5 }; -const unsigned char DSTAR_KENWOOD_DATA_MODE_BYTES[] = { 0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U }; -const unsigned char DSTAR_ICOM_DATA_MODE_BYTES[] = { 0xB2U, 0x4DU, 0x22U, 0x48U, 0xC0U, 0x16U, 0x28U, 0x26U, 0xC8U }; - const unsigned int DSTAR_VOICE_FRAME_LENGTH_BYTES = 9U; const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U; diff --git a/Utils.cpp b/Utils.cpp index 9bd8a06..49ded13 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -144,22 +144,3 @@ void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte) byte |= bits[6U] ? 0x40U : 0x00U; byte |= bits[7U] ? 0x80U : 0x00U; } - -unsigned int CUtils::compare(const unsigned char* bytes1, const unsigned char* bytes2, unsigned int length) -{ - assert(bytes1 != NULL); - assert(bytes2 != NULL); - - unsigned int diffs = 0U; - - for (unsigned int i = 0U; i < length; i++) { - unsigned char v = bytes1[i] ^ bytes2[i]; - while (v != 0U) { - v &= v - 1U; - diffs++; - } - } - - return diffs; -} - diff --git a/Utils.h b/Utils.h index 96a2d2c..ade28c0 100644 --- a/Utils.h +++ b/Utils.h @@ -30,8 +30,6 @@ public: static void bitsToByteBE(const bool* bits, unsigned char& byte); static void bitsToByteLE(const bool* bits, unsigned char& byte); - static unsigned int compare(const unsigned char* bytes1, const unsigned char* bytes2, unsigned int length); - private: }; From 8656aaedaa17f99838f7922e029876494a85d096 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Fri, 27 Nov 2020 18:14:53 -0500 Subject: [PATCH 15/19] Add back desired changes that were reverted --- DStarControl.cpp | 1 + DStarDefines.h | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index b553097..e8d7035 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -759,6 +759,7 @@ void CDStarControl::clock() } } + // Only insert silence on audio data if (m_netState == RS_NET_AUDIO) { m_packetTimer.clock(ms); diff --git a/DStarDefines.h b/DStarDefines.h index 498b35e..8c28991 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2018,2019 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 @@ -49,7 +49,10 @@ const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U; const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U; const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU; -const unsigned char DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U}; +// Data Frames are always scrambled using the first three bytes of +// DSTAR_SCRAMBLER_BYTES, and Voice Frames are scrambled with all nine +// bytes when Fast Data is in use +const unsigned char DSTAR_SCRAMBLER_BYTES[] = { 0x70U, 0x4FU, 0x93U, 0x40U, 0x64U, 0x74U, 0x6DU, 0x30U, 0x2BU }; const unsigned char DSTAR_DATA_MASK = 0x80U; const unsigned char DSTAR_REPEATER_MASK = 0x40U; From 8874d1262b1b6815954f08a04212b4a1a14ffd54 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Sat, 28 Nov 2020 15:53:54 -0500 Subject: [PATCH 16/19] Detect DV Fast Data on a per-frame basis This commit adds a maybeFixupVoiceFrame() function that is used by both the RF and Net code to manage FEC regeneration and DTMF blanking in voice frames. The presence of Fast Data is discovered by reading the mini-header in every second data frame. If found, FEC regeneration and DTMF blanking are disabled for the current and next voice frames. An exception is voice frames that have a sync frame instead of a data frame. This commit always disables FEC regeneration and DTMF blanking for these frames. A later commit will add support for these frames by setting aside the voice frame until the next data frame can be read. This commit also includes a number of debugging statements that will be removed in a later commit. --- DStarControl.cpp | 108 +++++++++++++++++++++++++++++++++++++---------- DStarControl.h | 22 ++++++++++ DStarDefines.h | 14 +++--- Defines.h | 2 + MMDVMHost.cpp | 2 +- 5 files changed, 119 insertions(+), 29 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index e8d7035..8cd57e5 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -23,6 +23,7 @@ #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) { @@ -83,7 +84,15 @@ m_minRSSI(0U), m_aveRSSI(0U), m_rssiCount(0U), m_enabled(true), -m_fp(NULL) +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) { assert(display != NULL); assert(rssiMapper != NULL); @@ -92,6 +101,8 @@ m_fp(NULL) m_gateway = new unsigned char[DSTAR_LONG_CALLSIGN_LENGTH]; m_lastFrame = new unsigned char[DSTAR_FRAME_LENGTH_BYTES + 1U]; + m_rfVoiceSyncData = new unsigned char[MODEM_DATA_LEN]; + m_netVoiceSyncData = new unsigned char[MODEM_DATA_LEN]; std::string call = callsign; call.resize(DSTAR_LONG_CALLSIGN_LENGTH - 1U, ' '); @@ -116,6 +127,56 @@ 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 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) { + LogMessage("%s frame %u: FEC regeneration disabled for first frame", log_prefix, n); + } 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; + LogMessage("%s frame %u: found fast data", log_prefix, n); + } else if (*next_frame_is_fast_data == true) { + *next_frame_is_fast_data = false; + if (blank_dtmf) + *skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; + LogMessage("%s frame %u: found fast data (cont.)", log_prefix, n); + } else { + errors = m_fec.regenerateDStar(data + offset); + LogMessage("%s frame %u: *** REGENERATING FEC ***", log_prefix, n); + + if (blank_dtmf && (*skip_dtmf_blanking_frames > 0U)) { + (*skip_dtmf_blanking_frames)--; + LogMessage("%s frame %u: *** Not BLANKING DTMF (left to skip: %u) ***", + log_prefix, n, *skip_dtmf_blanking_frames); + } else if (blank_dtmf && (*skip_dtmf_blanking_frames == 0U)) { + LogMessage("%s frame %u: *** BLANKING DTMF ***", log_prefix, n); + blankDTMF(data + offset); + } + } + + return errors; } bool CDStarControl::writeModem(unsigned char *data, unsigned int len) @@ -323,6 +384,9 @@ 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]; @@ -353,17 +417,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) return false; } else if (m_rfState == RS_RF_AUDIO) { - unsigned int errors = 0U; - if (!m_rfHeader.isDataPacket()) { - errors = m_fec.regenerateDStar(data + 1U); - m_display->writeDStarBER(float(errors) / 0.48F); - LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); - m_rfErrs += errors; - } - - m_rfBits += 48U; - m_rfFrames++; - // 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_rfN = 0U; @@ -374,13 +427,23 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_display->writeDStarRSSI(m_rssi); } + 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); + m_display->writeDStarBER(float(errors) / 0.48F); + LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); + m_rfErrs += errors; + } + + m_rfBits += 48U; + m_rfFrames++; + if (m_net) writeNetworkDataRF(data, errors, false); - if (m_duplex) { - blankDTMF(data + 1U); + if (m_duplex) writeQueueDataRF(data); - } m_rfN = (m_rfN + 1U) % 21U; } else if (m_rfState == RS_RF_LATE_ENTRY) { @@ -492,7 +555,8 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) unsigned int errors = 0U; if (!m_rfHeader.isDataPacket()) { - errors = m_fec.regenerateDStar(data + 1U); + errors = maybeFixupVoiceFrame(data, len, 1U, "RF", m_rfN, m_duplex, m_rfVoiceSyncData, &m_rfVoiceSyncDataLen, + &m_rfNextFrameIsFastData, &m_rfSkipDTMFBlankingFrames); LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F); m_rfErrs += errors; } @@ -502,10 +566,8 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) if (m_net) writeNetworkDataRF(data, errors, false); - if (m_duplex) { - blankDTMF(data + 1U); + if (m_duplex) writeQueueDataRF(data); - } m_rfState = RS_RF_AUDIO; @@ -670,6 +732,9 @@ 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]; @@ -690,9 +755,8 @@ void CDStarControl::writeNetwork() unsigned int errors = 0U; if (!m_netHeader.isDataPacket()) - errors = m_fec.regenerateDStar(data + 2U); - - blankDTMF(data + 2U); + errors = maybeFixupVoiceFrame(data, length, 2U, "Net", n, true, m_netVoiceSyncData, &m_netVoiceSyncDataLen, + &m_netNextFrameIsFastData, &m_netSkipDTMFBlankingFrames); data[1U] = TAG_DATA; diff --git a/DStarControl.h b/DStarControl.h index 3d541d1..1378c87 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -98,6 +98,28 @@ 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/DStarDefines.h b/DStarDefines.h index 8c28991..46f4c1d 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -42,12 +42,14 @@ const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U; const unsigned int DSTAR_LONG_CALLSIGN_LENGTH = 8U; const unsigned int DSTAR_SHORT_CALLSIGN_LENGTH = 4U; -const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U; -const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U; -const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U; -const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U; -const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U; -const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU; +const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U; +const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U; +const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U; +const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U; +const unsigned char DSTAR_SLOW_DATA_TYPE_FASTDATA01 = 0x80U; +const unsigned char DSTAR_SLOW_DATA_TYPE_FASTDATA16 = 0x90U; +const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U; +const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU; // Data Frames are always scrambled using the first three bytes of // DSTAR_SCRAMBLER_BYTES, and Voice Frames are scrambled with all nine diff --git a/Defines.h b/Defines.h index 8c57721..ebd75eb 100644 --- a/Defines.h +++ b/Defines.h @@ -39,6 +39,8 @@ const unsigned char TAG_DATA = 0x01U; const unsigned char TAG_LOST = 0x02U; const unsigned char TAG_EOT = 0x03U; +const unsigned int MODEM_DATA_LEN = 220U; + enum HW_TYPE { HWT_MMDVM, HWT_DVMEGA, diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 333b701..f100634 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -668,7 +668,7 @@ int CMMDVMHost::run() m_ump->setCD(cd); } - unsigned char data[220U]; + unsigned char data[MODEM_DATA_LEN]; unsigned int len; bool ret; From efe9b3d45956873da57e6a43832ddcf4edb26f74 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Sun, 29 Nov 2020 16:26:32 -0500 Subject: [PATCH 17/19] Process FEC and DTMF on Voice frames followed by Sync frame Rather than skipping FEC recalculation and DTMF blanking on Voice frames that do not have a corresponding mini-header (i.e. Voice frames followed by a Sync frame), set aside the frame's data. The data is processed and submitted to the modem/network during the next iteration, once the presence of DV Fast Data can be determined. --- DStarControl.cpp | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 8cd57e5..adc9de6 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -149,7 +149,9 @@ unsigned int CDStarControl::maybeFixupVoiceFrame( unsigned char mini_header_type = mini_header & DSTAR_SLOW_DATA_TYPE_MASK; if (n == 0U) { - LogMessage("%s frame %u: FEC regeneration disabled for first frame", log_prefix, n); + LogMessage("%s frame %u: delaying FEC and DTMF processing of first voice frame", log_prefix, n); + ::memcpy(voice_sync_data, data, 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))) { @@ -163,14 +165,25 @@ unsigned int CDStarControl::maybeFixupVoiceFrame( *skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; LogMessage("%s frame %u: found fast data (cont.)", log_prefix, n); } else { - errors = m_fec.regenerateDStar(data + offset); + if (n == 1U) { + LogMessage("%s frame 0: *** REGENERATING FEC ***", log_prefix); + errors += m_fec.regenerateDStar(voice_sync_data + offset); + } LogMessage("%s frame %u: *** REGENERATING FEC ***", log_prefix, n); + errors += m_fec.regenerateDStar(data + offset); if (blank_dtmf && (*skip_dtmf_blanking_frames > 0U)) { (*skip_dtmf_blanking_frames)--; + if (n == 1U) + LogMessage("%s frame 0: *** Not BLANKING DTMF (left to skip: %u) ***", + log_prefix, *skip_dtmf_blanking_frames); LogMessage("%s frame %u: *** Not BLANKING DTMF (left to skip: %u) ***", log_prefix, n, *skip_dtmf_blanking_frames); } else if (blank_dtmf && (*skip_dtmf_blanking_frames == 0U)) { + if (n == 1U) { + LogMessage("%s frame 0: *** BLANKING DTMF ***", log_prefix); + blankDTMF(voice_sync_data + offset); + } LogMessage("%s frame %u: *** BLANKING DTMF ***", log_prefix, n); blankDTMF(data + offset); } @@ -439,11 +452,19 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_rfBits += 48U; m_rfFrames++; - if (m_net) - writeNetworkDataRF(data, errors, false); + if (m_net) { + if (m_rfN == 1U) + writeNetworkDataRF(m_rfVoiceSyncData, 0U, false); + if (m_rfN >= 1U) + writeNetworkDataRF(data, errors, false); + } - if (m_duplex) - writeQueueDataRF(data); + if (m_duplex) { + if (m_rfN == 1U) + writeQueueDataRF(m_rfVoiceSyncData); + if (m_rfN >= 1U) + writeQueueDataRF(data); + } m_rfN = (m_rfN + 1U) % 21U; } else if (m_rfState == RS_RF_LATE_ENTRY) { @@ -753,13 +774,13 @@ void CDStarControl::writeNetwork() 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); - data[1U] = TAG_DATA; - // Insert silence and reject if in the past bool ret = insertSilence(data + 1U, n); if (!ret) @@ -778,9 +799,15 @@ void CDStarControl::writeNetwork() m_netFrames++; #if defined(DUMP_DSTAR) - writeFile(data + 1U, length - 1U); + if (n == 1U) + writeFile(m_netVoiceSyncData + 1U, m_netVoiceSyncDataLen - 1U); + if (n >= 1U) + writeFile(data + 1U, length - 1U); #endif - writeQueueDataNet(data + 1U); + if (n == 1U) + writeQueueDataNet(m_netVoiceSyncData + 1U); + if (n >= 1U) + writeQueueDataNet(data + 1U); } else { CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U); } From b2844bc0a6a47a906d6a120942be322ccca03b34 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Sun, 13 Dec 2020 16:28:47 -0500 Subject: [PATCH 18/19] Avoid FEC regeneration and DTMF blanking for null AMBE data FEC recalculation always reports errors for null AMBE frames, and there is no DTMF present by definition. In practice, null AMBE data is often (always?) sent by the Kenwood TH-D74 in the first 21 voice frames, and I've also seen it at the end of a fast data transmission. --- DStarControl.cpp | 27 +++++++++++++++++++++------ DStarDefines.h | 2 ++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index adc9de6..95e3096 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -165,12 +165,25 @@ unsigned int CDStarControl::maybeFixupVoiceFrame( *skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; LogMessage("%s frame %u: found fast data (cont.)", log_prefix, n); } else { - if (n == 1U) { + 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)) { + LogMessage("%s frame 0: *** Null AMBE data detected in voice frame ***", log_prefix); + voice_sync_data_is_null_ambe_data = true; + } + if (::memcmp(data + offset, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0) { + LogMessage("%s frame %u: *** Null AMBE data detected in voice frame ***", log_prefix, n); + data_is_null_ambe_data = true; + } + + if ((n == 1U) && !voice_sync_data_is_null_ambe_data) { LogMessage("%s frame 0: *** REGENERATING FEC ***", log_prefix); errors += m_fec.regenerateDStar(voice_sync_data + offset); } - LogMessage("%s frame %u: *** REGENERATING FEC ***", log_prefix, n); - errors += m_fec.regenerateDStar(data + offset); + if (!data_is_null_ambe_data) { + LogMessage("%s frame %u: *** REGENERATING FEC ***", log_prefix, n); + errors += m_fec.regenerateDStar(data + offset); + } if (blank_dtmf && (*skip_dtmf_blanking_frames > 0U)) { (*skip_dtmf_blanking_frames)--; @@ -180,12 +193,14 @@ unsigned int CDStarControl::maybeFixupVoiceFrame( LogMessage("%s frame %u: *** Not BLANKING DTMF (left to skip: %u) ***", log_prefix, n, *skip_dtmf_blanking_frames); } else if (blank_dtmf && (*skip_dtmf_blanking_frames == 0U)) { - if (n == 1U) { + if ((n == 1U) && !voice_sync_data_is_null_ambe_data) { LogMessage("%s frame 0: *** BLANKING DTMF ***", log_prefix); blankDTMF(voice_sync_data + offset); } - LogMessage("%s frame %u: *** BLANKING DTMF ***", log_prefix, n); - blankDTMF(data + offset); + if (!data_is_null_ambe_data) { + LogMessage("%s frame %u: *** BLANKING DTMF ***", log_prefix, n); + blankDTMF(data + offset); + } } } diff --git a/DStarDefines.h b/DStarDefines.h index 46f4c1d..2a3e90c 100644 --- a/DStarDefines.h +++ b/DStarDefines.h @@ -28,6 +28,8 @@ const unsigned char DSTAR_END_PATTERN_BYTES[] = { TAG_EOT, 0x55, 0x55, 0x55, 0x5 const unsigned int DSTAR_END_PATTERN_LENGTH_BYTES = 6U; const unsigned char DSTAR_NULL_AMBE_DATA_BYTES[] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8 }; +// DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED is DSTAR_NULL_AMBE_DATA_BYTES XORed with DSTAR_SCRAMBLER_BYTES. +const unsigned char DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED[] = { 0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U }; const unsigned char DSTAR_NULL_SLOW_SYNC_BYTES[] = { 0x55, 0x2D, 0x16 }; // Note that these are already scrambled, 0x66 0x66 0x66 otherwise From bf5651b7a0c576f4baa0690653040fb15e6e4692 Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Sun, 29 Nov 2020 21:36:16 -0500 Subject: [PATCH 19/19] Remove DV Fast Data debugging statements --- DStarControl.cpp | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index 95e3096..794b748 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -149,7 +149,6 @@ unsigned int CDStarControl::maybeFixupVoiceFrame( unsigned char mini_header_type = mini_header & DSTAR_SLOW_DATA_TYPE_MASK; if (n == 0U) { - LogMessage("%s frame %u: delaying FEC and DTMF processing of first voice frame", log_prefix, n); ::memcpy(voice_sync_data, data, MODEM_DATA_LEN); *voice_sync_data_len = len; } else if ((n % 2U != 0U) && @@ -158,49 +157,30 @@ unsigned int CDStarControl::maybeFixupVoiceFrame( *next_frame_is_fast_data = true; if (blank_dtmf) *skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; - LogMessage("%s frame %u: found fast data", log_prefix, n); } else if (*next_frame_is_fast_data == true) { *next_frame_is_fast_data = false; if (blank_dtmf) *skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES; - LogMessage("%s frame %u: found fast data (cont.)", 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)) { - LogMessage("%s frame 0: *** Null AMBE data detected in voice frame ***", log_prefix); + 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) { - LogMessage("%s frame %u: *** Null AMBE data detected in voice frame ***", log_prefix, n); + 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) { - LogMessage("%s frame 0: *** REGENERATING FEC ***", log_prefix); + if ((n == 1U) && !voice_sync_data_is_null_ambe_data) errors += m_fec.regenerateDStar(voice_sync_data + offset); - } - if (!data_is_null_ambe_data) { - LogMessage("%s frame %u: *** REGENERATING FEC ***", log_prefix, n); + if (!data_is_null_ambe_data) errors += m_fec.regenerateDStar(data + offset); - } if (blank_dtmf && (*skip_dtmf_blanking_frames > 0U)) { (*skip_dtmf_blanking_frames)--; - if (n == 1U) - LogMessage("%s frame 0: *** Not BLANKING DTMF (left to skip: %u) ***", - log_prefix, *skip_dtmf_blanking_frames); - LogMessage("%s frame %u: *** Not BLANKING DTMF (left to skip: %u) ***", - log_prefix, n, *skip_dtmf_blanking_frames); } else if (blank_dtmf && (*skip_dtmf_blanking_frames == 0U)) { - if ((n == 1U) && !voice_sync_data_is_null_ambe_data) { - LogMessage("%s frame 0: *** BLANKING DTMF ***", log_prefix); + if ((n == 1U) && !voice_sync_data_is_null_ambe_data) blankDTMF(voice_sync_data + offset); - } - if (!data_is_null_ambe_data) { - LogMessage("%s frame %u: *** BLANKING DTMF ***", log_prefix, n); + if (!data_is_null_ambe_data) blankDTMF(data + offset); - } } }