From e1b164de705fb8718e4d97bd16abab3059693f00 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 19 Aug 2021 20:44:15 +0100 Subject: [PATCH 01/11] Add the new EOF frame. --- M17Control.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++----- M17Defines.h | 4 ++ Version.h | 2 +- 3 files changed, 107 insertions(+), 12 deletions(-) diff --git a/M17Control.cpp b/M17Control.cpp index 4b2cfdc..afef9e6 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -256,7 +256,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) uint16_t fn = (frame[0U] << 8) + (frame[1U] << 0); - LogDebug("M17, audio: FN: %u, errs: %u/272 (%.1f%%)", fn & 0x7FFFU, errors, float(errors) / 2.72F); + LogDebug("M17, audio: FN: %u, errs: %u/272 (%.1f%%)", fn, errors, float(errors) / 2.72F); m_rfBits += 272U; m_rfErrs += errors; @@ -319,20 +319,78 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) if (m_rfLSFn >= 6U) m_rfLSFn = 0U; - bool bValid = (fn & 0x7FFFU) < (210U * 25U); // 210 seconds maximum - bool bEnd = (fn & 0x8000U) == 0x8000U; + return true; + } - if (bValid && bEnd) { - std::string source = m_rfLSF.getSource(); - std::string dest = m_rfLSF.getDest(); + if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO) && data[0U] == TAG_HEADER) { +#if defined(DUMP_M17) + writeFile(data + 2U); +#endif - if (m_rssi != 0U) - LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); - else - LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits)); - writeEndRF(); + std::string source = m_rfLSF.getSource(); + std::string dest = m_rfLSF.getDest(); + + if (m_duplex) { + unsigned char rfData[M17_FRAME_LENGTH_BYTES + 2U]; + + // Create a Link Setup frame + rfData[0U] = TAG_HEADER; + rfData[1U] = 0x00U; + + // Generate the sync + CSync::addM17LinkSetupSync(rfData + 2U); + + CM17LSF lsf; + lsf.setSource(source); + lsf.setDest(dest); + lsf.setPacketStream(M17_STREAM_TYPE); + lsf.setDataType(M17_DATA_TYPE_END); + lsf.setEncryptionType(M17_ENCRYPTION_TYPE_NONE); + lsf.setEncryptionSubType(M17_ENCRYPTION_SUB_TYPE_TEXT); + lsf.setMeta(M17_NULL_NONCE); + + unsigned char setup[M17_LSF_LENGTH_BYTES]; + lsf.getLinkSetup(setup); + + // Add the convolution FEC + CM17Convolution conv; + conv.encodeLinkSetup(setup, rfData + 2U + M17_SYNC_LENGTH_BYTES); + + unsigned char temp[M17_FRAME_LENGTH_BYTES]; + interleaver(rfData + 2U, temp); + decorrelator(temp, rfData + 2U); + + writeQueueRF(rfData); } + if (m_network != NULL && m_rfTimeoutTimer.isRunning() && !m_rfTimeoutTimer.hasExpired()) { + unsigned char netData[M17_LSF_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; + + m_rfLSF.getNetwork(netData + 0U); + + // Add a EOF FN and silence for the EOF frame + netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] = 0x80U; + netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 1U] = 0x00U; + + if (m_rfState == RS_RF_AUDIO) { + ::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_3200_SILENCE, 8U); + ::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, M17_3200_SILENCE, 8U); + } else { + ::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_1600_SILENCE, 8U); + ::memset(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, 0x00U, 8U); + } + + // The CRC is added in the networking code + + m_network->write(netData); + } + + if (m_rssi != 0U) + LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); + else + LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits)); + writeEndRF(); + return true; } @@ -519,7 +577,40 @@ void CM17Control::writeNetwork() if ((fn & 0x8000U) == 0x8000U) { std::string source = m_netLSF.getSource(); std::string dest = m_netLSF.getDest(); + LogMessage("M17, received network end of transmission from %s to %s, %.1f seconds", source.c_str(), dest.c_str(), float(m_netFrames) / 25.0F); + + unsigned char rfData[M17_FRAME_LENGTH_BYTES + 2U]; + + // Create a Link Setup frame + rfData[0U] = TAG_HEADER; + rfData[1U] = 0x00U; + + // Generate the sync + CSync::addM17LinkSetupSync(rfData + 2U); + + CM17LSF lsf; + lsf.setSource(source); + lsf.setDest(dest); + lsf.setPacketStream(M17_STREAM_TYPE); + lsf.setDataType(M17_DATA_TYPE_END); + lsf.setEncryptionType(M17_ENCRYPTION_TYPE_NONE); + lsf.setEncryptionSubType(M17_ENCRYPTION_SUB_TYPE_TEXT); + lsf.setMeta(M17_NULL_NONCE); + + unsigned char setup[M17_LSF_LENGTH_BYTES]; + lsf.getLinkSetup(setup); + + // Add the convolution FEC + CM17Convolution conv; + conv.encodeLinkSetup(setup, rfData + 2U + M17_SYNC_LENGTH_BYTES); + + unsigned char temp[M17_FRAME_LENGTH_BYTES]; + interleaver(rfData + 2U, temp); + decorrelator(temp, rfData + 2U); + + writeQueueRF(rfData); + writeEndNet(); } } diff --git a/M17Defines.h b/M17Defines.h index dd2fe37..223e229 100644 --- a/M17Defines.h +++ b/M17Defines.h @@ -64,6 +64,7 @@ const unsigned char M17_1600_SILENCE[] = {0x01U, 0x00U, 0x04U, 0x00U, 0x25U, 0x7 const unsigned char M17_PACKET_TYPE = 0U; const unsigned char M17_STREAM_TYPE = 1U; +const unsigned char M17_DATA_TYPE_END = 0x00U; const unsigned char M17_DATA_TYPE_DATA = 0x01U; const unsigned char M17_DATA_TYPE_VOICE = 0x02U; const unsigned char M17_DATA_TYPE_VOICE_DATA = 0x03U; @@ -72,4 +73,7 @@ const unsigned char M17_ENCRYPTION_TYPE_NONE = 0x00U; const unsigned char M17_ENCRYPTION_TYPE_AES = 0x01U; const unsigned char M17_ENCRYPTION_TYPE_SCRAMBLE = 0x02U; +const unsigned char M17_ENCRYPTION_SUB_TYPE_TEXT = 0x00U; +const unsigned char M17_ENCRYPTION_SUB_TYPE_GPS = 0x01U; + #endif diff --git a/Version.h b/Version.h index c4fd038..47217f7 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20210818"; +const char* VERSION = "20210819"; #endif From 293962a7f7dfb83c361a78eac9a2fa7b9432eede Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 19 Aug 2021 20:50:31 +0100 Subject: [PATCH 02/11] Filter the EOF marker out of the FN for retransmission. --- M17Control.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/M17Control.cpp b/M17Control.cpp index afef9e6..3c3337f 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -556,7 +556,12 @@ void CM17Control::writeNetwork() // Add the FN and the data/audio unsigned char payload[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES]; - ::memcpy(payload, netData + 28U, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); + + // Copy the FN minus the EOF marker + payload[0U] = netData[28U] & 0x7FU; + payload[1U] = netData[29U]; + + ::memcpy(payload + 2U, netData + 30U, M17_PAYLOAD_LENGTH_BYTES); // Add the Convolution FEC CM17Convolution conv; From 55f4c6ce1aa1de3b24e1e58d168447aeae30ad02 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 19 Aug 2021 21:39:29 +0100 Subject: [PATCH 03/11] Fix small queueing bug. --- M17Control.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/M17Control.cpp b/M17Control.cpp index 3c3337f..deb6301 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -614,7 +614,7 @@ void CM17Control::writeNetwork() interleaver(rfData + 2U, temp); decorrelator(temp, rfData + 2U); - writeQueueRF(rfData); + writeQueueNet(rfData); writeEndNet(); } From fbb835812d2860946febbf75959e60373ea15ea3 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 20 Aug 2021 07:08:18 +0100 Subject: [PATCH 04/11] Clean up the new EOF handling. --- M17Control.cpp | 34 +++++++++------------------------- Version.h | 2 +- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/M17Control.cpp b/M17Control.cpp index deb6301..acf1453 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -307,6 +307,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) // Copy the FN and payload from the frame ::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES, frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); + netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] |= 0x80U; // The CRC is added in the networking code @@ -326,10 +327,6 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) #if defined(DUMP_M17) writeFile(data + 2U); #endif - - std::string source = m_rfLSF.getSource(); - std::string dest = m_rfLSF.getDest(); - if (m_duplex) { unsigned char rfData[M17_FRAME_LENGTH_BYTES + 2U]; @@ -340,17 +337,10 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) // Generate the sync CSync::addM17LinkSetupSync(rfData + 2U); - CM17LSF lsf; - lsf.setSource(source); - lsf.setDest(dest); - lsf.setPacketStream(M17_STREAM_TYPE); - lsf.setDataType(M17_DATA_TYPE_END); - lsf.setEncryptionType(M17_ENCRYPTION_TYPE_NONE); - lsf.setEncryptionSubType(M17_ENCRYPTION_SUB_TYPE_TEXT); - lsf.setMeta(M17_NULL_NONCE); + m_rfLSF.setDataType(M17_DATA_TYPE_END); unsigned char setup[M17_LSF_LENGTH_BYTES]; - lsf.getLinkSetup(setup); + m_rfLSF.getLinkSetup(setup); // Add the convolution FEC CM17Convolution conv; @@ -385,6 +375,9 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) m_network->write(netData); } + std::string source = m_rfLSF.getSource(); + std::string dest = m_rfLSF.getDest(); + if (m_rssi != 0U) LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); else @@ -594,17 +587,10 @@ void CM17Control::writeNetwork() // Generate the sync CSync::addM17LinkSetupSync(rfData + 2U); - CM17LSF lsf; - lsf.setSource(source); - lsf.setDest(dest); - lsf.setPacketStream(M17_STREAM_TYPE); - lsf.setDataType(M17_DATA_TYPE_END); - lsf.setEncryptionType(M17_ENCRYPTION_TYPE_NONE); - lsf.setEncryptionSubType(M17_ENCRYPTION_SUB_TYPE_TEXT); - lsf.setMeta(M17_NULL_NONCE); + m_netLSF.setDataType(M17_DATA_TYPE_END); unsigned char setup[M17_LSF_LENGTH_BYTES]; - lsf.getLinkSetup(setup); + m_netLSF.getLinkSetup(setup); // Add the convolution FEC CM17Convolution conv; @@ -667,9 +653,7 @@ bool CM17Control::processRFHeader(bool lateEntry) m_rfState = RS_RF_DATA_AUDIO; break; default: - LogMessage("M17, received RF%sunknown transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str()); - m_rfState = RS_RF_DATA; - break; + return false; } m_display->writeM17(source.c_str(), dest.c_str(), "R"); diff --git a/Version.h b/Version.h index 47217f7..8f382b6 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20210819"; +const char* VERSION = "20210820"; #endif From 8c31fe6f3467e014b97c492af9d8d2873f2d1a2e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 20 Aug 2021 09:23:39 +0100 Subject: [PATCH 05/11] Fix a bug introduced in the new EOF processing. --- M17Control.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/M17Control.cpp b/M17Control.cpp index acf1453..e11b26d 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -307,7 +307,9 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) // Copy the FN and payload from the frame ::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES, frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); - netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] |= 0x80U; + // Remove any erronous EOF from the FN + netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] &= 0x7FU; + // The CRC is added in the networking code @@ -450,8 +452,10 @@ void CM17Control::writeNetwork() if (!m_enabled) return; - if (m_rfState != RS_RF_LISTENING && m_rfState != RS_RF_LATE_ENTRY && m_netState == RS_NET_IDLE) + if (m_rfState != RS_RF_LISTENING && m_rfState != RS_RF_LATE_ENTRY && m_netState == RS_NET_IDLE) { + m_network->reset(); return; + } m_networkWatchdog.start(); @@ -460,8 +464,10 @@ void CM17Control::writeNetwork() if (!m_allowEncryption) { unsigned char type = m_netLSF.getEncryptionType(); - if (type != M17_ENCRYPTION_TYPE_NONE) + if (type != M17_ENCRYPTION_TYPE_NONE) { + m_network->reset(); return; + } } if (m_netState == RS_NET_IDLE) { @@ -483,9 +489,8 @@ void CM17Control::writeNetwork() m_netState = RS_NET_DATA_AUDIO; break; default: - LogMessage("M17, received network unknown transmission from %s to %s", source.c_str(), dest.c_str()); - m_netState = RS_NET_DATA; - break; + m_network->reset(); + return; } m_display->writeM17(source.c_str(), dest.c_str(), "N"); From 8e36cd88aa9c9e8795c86deef67c650f3870453d Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 20 Aug 2021 16:10:21 +0100 Subject: [PATCH 06/11] Update the 1600 silence bytes. --- M17Defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/M17Defines.h b/M17Defines.h index 223e229..5872c55 100644 --- a/M17Defines.h +++ b/M17Defines.h @@ -59,7 +59,7 @@ const unsigned int M17_CRC_LENGTH_BITS = 16U; const unsigned int M17_CRC_LENGTH_BYTES = M17_CRC_LENGTH_BITS / 8U; const unsigned char M17_3200_SILENCE[] = {0x01U, 0x00U, 0x09U, 0x43U, 0x9CU, 0xE4U, 0x21U, 0x08U}; -const unsigned char M17_1600_SILENCE[] = {0x01U, 0x00U, 0x04U, 0x00U, 0x25U, 0x75U, 0xDDU, 0xF2U}; +const unsigned char M17_1600_SILENCE[] = {0x0CU, 0x41U, 0x09U, 0x03U, 0x0CU, 0x41U, 0x09U, 0x03U}; const unsigned char M17_PACKET_TYPE = 0U; const unsigned char M17_STREAM_TYPE = 1U; From 836bc0dc9bd8a288af3e677d101d00b79072e164 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 23 Aug 2021 23:03:52 +0100 Subject: [PATCH 07/11] Update to the latest Link Setup puncturing pattern. --- M17Convolution.cpp | 18 +++++++++--------- Version.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/M17Convolution.cpp b/M17Convolution.cpp index 7b2b02f..a43991b 100644 --- a/M17Convolution.cpp +++ b/M17Convolution.cpp @@ -23,21 +23,21 @@ #include #include -const unsigned int PUNCTURE_LIST_LINK_SETUP_COUNT = 60U; +const unsigned int PUNCTURE_LIST_LINK_SETUP_COUNT = 61U; const unsigned int PUNCTURE_LIST_LINK_SETUP[] = { - 3U, 6U, 9U, 12U, 19U, 22U, 25U, 28U, 35U, 38U, 41U, 44U, 51U, 54U, 57U, 64U, 67U, 70U, 73U, 80U, 83U, 86U, 89U, 96U, 99U, 102U, - 105U, 112U, 115U, 118U, 125U, 128U, 131U, 134U, 141U, 144U, 147U, 150U, 157U, 160U, 163U, 166U, 173U, 176U, 179U, 186U, 189U, - 192U, 195U, 202U, 205U, 208U, 211U, 218U, 221U, 224U, 227U, 234U, 237U, 240U, 247U, 250U, 253U, 256U, 263U, 266U, 269U, 272U, - 279U, 282U, 285U, 288U, 295U, 298U, 301U, 308U, 311U, 314U, 317U, 324U, 327U, 330U, 333U, 340U, 343U, 346U, 349U, 356U, 359U, - 362U, 369U, 372U, 375U, 378U, 385U, 388U, 391U, 394U, 401U, 404U, 407U, 410U, 417U, 420U, 423U, 430U, 433U, 436U, 439U, 446U, - 449U, 452U, 455U, 462U, 465U, 468U, 471U, 478U, 481U, 484U}; + 2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, 50U, 54U, 58U, 62U, 66U, 70U, 74U, 78U, 82U, + 86U, 90U, 94U, 98U, 102U, 106U, 110U, 114U, 118U, 122U, 126U, 130U, 134U, 138U, 142U, 146U, 150U, 154U, 158U, 162U, 166U, + 170U, 174U, 178U, 182U, 186U, 190U, 194U, 198U, 202U, 206U, 210U, 214U, 218U, 222U, 226U, 230U, 234U, 238U, 242U, 246U, 250U, + 254U, 258U, 262U, 266U, 270U, 274U, 278U, 282U, 286U, 290U, 294U, 298U, 302U, 306U, 310U, 314U, 318U, 322U, 326U, 330U, 334U, + 338U, 342U, 346U, 350U, 354U, 358U, 362U, 366U, 370U, 374U, 378U, 382U, 386U, 390U, 394U, 398U, 402U, 406U, 410U, 414U, 418U, + 422U, 426U, 430U, 434U, 438U, 442U, 446U, 450U, 454U, 458U, 462U, 466U, 470U, 474U, 478U, 482U, 486U}; const unsigned int PUNCTURE_LIST_DATA_COUNT = 12U; const unsigned int PUNCTURE_LIST_DATA[] = { - 11U, 23U, 35U, 47U, 59U, 71U, 83U, 95U, 107U, 119U, 131U, 143U, 155U, 167U, 179U, 191U, 203U, 215U, 227U, 239U, 251U, 263U, - 275U, 287U, 299U, 311U, 323U }; + 11U, 23U, 35U, 47U, 59U, 71U, 83U, 95U, 107U, 119U, 131U, 143U, 155U, 167U, 179U, 191U, 203U, 215U, 227U, 239U, 251U, + 263U, 275U, 287U}; const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; diff --git a/Version.h b/Version.h index c4fd038..5e64e73 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20210818"; +const char* VERSION = "20210823"; #endif From b779ea5ae621b755dee3b48a82caf39023649637 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 25 Aug 2021 19:27:53 +0100 Subject: [PATCH 08/11] Convert to the new EOF marker. --- M17Control.cpp | 98 ++++++++++++++++++++++++-------------------------- M17Control.h | 4 +++ M17Defines.h | 1 - Modem.cpp | 41 +++++++++++++++------ Version.h | 2 +- 5 files changed, 82 insertions(+), 64 deletions(-) diff --git a/M17Control.cpp b/M17Control.cpp index e11b26d..50664a7 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -325,35 +325,12 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) return true; } - if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO) && data[0U] == TAG_HEADER) { + if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO) && data[0U] == TAG_EOT) { #if defined(DUMP_M17) writeFile(data + 2U); #endif - if (m_duplex) { - unsigned char rfData[M17_FRAME_LENGTH_BYTES + 2U]; - - // Create a Link Setup frame - rfData[0U] = TAG_HEADER; - rfData[1U] = 0x00U; - - // Generate the sync - CSync::addM17LinkSetupSync(rfData + 2U); - - m_rfLSF.setDataType(M17_DATA_TYPE_END); - - unsigned char setup[M17_LSF_LENGTH_BYTES]; - m_rfLSF.getLinkSetup(setup); - - // Add the convolution FEC - CM17Convolution conv; - conv.encodeLinkSetup(setup, rfData + 2U + M17_SYNC_LENGTH_BYTES); - - unsigned char temp[M17_FRAME_LENGTH_BYTES]; - interleaver(rfData + 2U, temp); - decorrelator(temp, rfData + 2U); - - writeQueueRF(rfData); - } + if (m_duplex) + writeQueueEOTRF(); if (m_network != NULL && m_rfTimeoutTimer.isRunning() && !m_rfTimeoutTimer.hasExpired()) { unsigned char netData[M17_LSF_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; @@ -583,29 +560,7 @@ void CM17Control::writeNetwork() LogMessage("M17, received network end of transmission from %s to %s, %.1f seconds", source.c_str(), dest.c_str(), float(m_netFrames) / 25.0F); - unsigned char rfData[M17_FRAME_LENGTH_BYTES + 2U]; - - // Create a Link Setup frame - rfData[0U] = TAG_HEADER; - rfData[1U] = 0x00U; - - // Generate the sync - CSync::addM17LinkSetupSync(rfData + 2U); - - m_netLSF.setDataType(M17_DATA_TYPE_END); - - unsigned char setup[M17_LSF_LENGTH_BYTES]; - m_netLSF.getLinkSetup(setup); - - // Add the convolution FEC - CM17Convolution conv; - conv.encodeLinkSetup(setup, rfData + 2U + M17_SYNC_LENGTH_BYTES); - - unsigned char temp[M17_FRAME_LENGTH_BYTES]; - interleaver(rfData + 2U, temp); - decorrelator(temp, rfData + 2U); - - writeQueueNet(rfData); + writeQueueEOTNet(); writeEndNet(); } @@ -718,7 +673,7 @@ void CM17Control::writeQueueRF(const unsigned char *data) if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired()) return; - unsigned char len = M17_FRAME_LENGTH_BYTES + 2U; + const unsigned char len = M17_FRAME_LENGTH_BYTES + 2U; unsigned int space = m_queue.freeSpace(); if (space < (len + 1U)) { @@ -731,6 +686,28 @@ void CM17Control::writeQueueRF(const unsigned char *data) m_queue.addData(data, len); } +void CM17Control::writeQueueEOTRF() +{ + if (m_netState != RS_NET_IDLE) + return; + + if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired()) + return; + + const unsigned char len = 1U; + + unsigned int space = m_queue.freeSpace(); + if (space < (len + 1U)) { + LogError("M17, overflow in the M17 RF queue"); + return; + } + + m_queue.addData(&len, 1U); + + const unsigned char data = TAG_EOT; + m_queue.addData(&data, len); +} + void CM17Control::writeQueueNet(const unsigned char *data) { assert(data != NULL); @@ -738,7 +715,7 @@ void CM17Control::writeQueueNet(const unsigned char *data) if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired()) return; - unsigned char len = M17_FRAME_LENGTH_BYTES + 2U; + const unsigned char len = M17_FRAME_LENGTH_BYTES + 2U; unsigned int space = m_queue.freeSpace(); if (space < (len + 1U)) { @@ -751,6 +728,25 @@ void CM17Control::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } +void CM17Control::writeQueueEOTNet() +{ + if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired()) + return; + + const unsigned char len = 1U; + + unsigned int space = m_queue.freeSpace(); + if (space < (len + 1U)) { + LogError("M17, overflow in the M17 RF queue"); + return; + } + + m_queue.addData(&len, 1U); + + const unsigned char data = TAG_EOT; + m_queue.addData(&data, len); +} + void CM17Control::interleaver(const unsigned char* in, unsigned char* out) const { assert(in != NULL); diff --git a/M17Control.h b/M17Control.h index 5339d33..f7cc775 100644 --- a/M17Control.h +++ b/M17Control.h @@ -82,7 +82,11 @@ private: bool processRFHeader(bool lateEntry); void writeQueueRF(const unsigned char* data); + void writeQueueEOTRF(); + void writeQueueNet(const unsigned char* data); + void writeQueueEOTNet(); + void writeNetwork(); void interleaver(const unsigned char* in, unsigned char* out) const; diff --git a/M17Defines.h b/M17Defines.h index 5872c55..ab69859 100644 --- a/M17Defines.h +++ b/M17Defines.h @@ -64,7 +64,6 @@ const unsigned char M17_1600_SILENCE[] = {0x0CU, 0x41U, 0x09U, 0x03U, 0x0CU, 0x4 const unsigned char M17_PACKET_TYPE = 0U; const unsigned char M17_STREAM_TYPE = 1U; -const unsigned char M17_DATA_TYPE_END = 0x00U; const unsigned char M17_DATA_TYPE_DATA = 0x01U; const unsigned char M17_DATA_TYPE_VOICE = 0x02U; const unsigned char M17_DATA_TYPE_VOICE_DATA = 0x03U; diff --git a/Modem.cpp b/Modem.cpp index 2ff14f2..6287aa8 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -78,6 +78,7 @@ const unsigned char MMDVM_M17_LINK_SETUP = 0x45U; const unsigned char MMDVM_M17_STREAM = 0x46U; const unsigned char MMDVM_M17_PACKET = 0x47U; const unsigned char MMDVM_M17_LOST = 0x48U; +const unsigned char MMDVM_M17_EOT = 0x49U; const unsigned char MMDVM_POCSAG_DATA = 0x50U; @@ -690,6 +691,18 @@ void CModem::clock(unsigned int ms) } break; + case MMDVM_M17_EOT: { + if (m_trace) + CUtils::dump(1U, "RX M17 EOT", m_buffer, m_length); + + unsigned char data = 1U; + m_rxM17Data.addData(&data, 1U); + + data = TAG_EOT; + m_rxM17Data.addData(&data, 1U); + } + break; + case MMDVM_M17_LOST: { if (m_trace) CUtils::dump(1U, "RX M17 Lost", m_buffer, m_length); @@ -1041,8 +1054,8 @@ void CModem::clock(unsigned int ms) case MMDVM_M17_STREAM: CUtils::dump(1U, "TX M17 Stream Data", m_buffer, len); break; - case MMDVM_M17_PACKET: - CUtils::dump(1U, "TX M17 Packet Data", m_buffer, len); + case MMDVM_M17_EOT: + CUtils::dump(1U, "TX M17 EOT", m_buffer, len); break; } } @@ -1504,20 +1517,26 @@ bool CModem::writeM17Data(const unsigned char* data, unsigned int length) assert(data != NULL); assert(length > 0U); - if (data[0U] != TAG_HEADER && data[0U] != TAG_DATA && data[0U] != TAG_EOT) - return false; - unsigned char buffer[130U]; buffer[0U] = MMDVM_FRAME_START; buffer[1U] = length + 2U; - if (data[0U] == TAG_HEADER) - buffer[2U] = MMDVM_M17_LINK_SETUP; - else - buffer[2U] = MMDVM_M17_STREAM; - - ::memcpy(buffer + 3U, data + 1U, length - 1U); + switch (data[0U]) { + case TAG_HEADER: + buffer[2U] = MMDVM_M17_LINK_SETUP; + ::memcpy(buffer + 3U, data + 1U, length - 1U); + break; + case TAG_DATA: + buffer[2U] = MMDVM_M17_STREAM; + ::memcpy(buffer + 3U, data + 1U, length - 1U); + break; + case TAG_EOT: + buffer[2U] = MMDVM_M17_EOT; + break; + default: + return false; + } unsigned char len = length + 2U; m_txM17Data.addData(&len, 1U); diff --git a/Version.h b/Version.h index 5e64e73..a42db6c 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20210823"; +const char* VERSION = "20210825"; #endif From 11f14465e69dbf94702e24b61eba616351355401 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 5 Sep 2021 14:59:15 +0100 Subject: [PATCH 09/11] Fix the Link Setup puncturing matrix. --- M17Convolution.cpp | 12 ++++++------ Version.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/M17Convolution.cpp b/M17Convolution.cpp index a43991b..aa9226c 100644 --- a/M17Convolution.cpp +++ b/M17Convolution.cpp @@ -26,12 +26,12 @@ const unsigned int PUNCTURE_LIST_LINK_SETUP_COUNT = 61U; const unsigned int PUNCTURE_LIST_LINK_SETUP[] = { - 2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, 50U, 54U, 58U, 62U, 66U, 70U, 74U, 78U, 82U, - 86U, 90U, 94U, 98U, 102U, 106U, 110U, 114U, 118U, 122U, 126U, 130U, 134U, 138U, 142U, 146U, 150U, 154U, 158U, 162U, 166U, - 170U, 174U, 178U, 182U, 186U, 190U, 194U, 198U, 202U, 206U, 210U, 214U, 218U, 222U, 226U, 230U, 234U, 238U, 242U, 246U, 250U, - 254U, 258U, 262U, 266U, 270U, 274U, 278U, 282U, 286U, 290U, 294U, 298U, 302U, 306U, 310U, 314U, 318U, 322U, 326U, 330U, 334U, - 338U, 342U, 346U, 350U, 354U, 358U, 362U, 366U, 370U, 374U, 378U, 382U, 386U, 390U, 394U, 398U, 402U, 406U, 410U, 414U, 418U, - 422U, 426U, 430U, 434U, 438U, 442U, 446U, 450U, 454U, 458U, 462U, 466U, 470U, 474U, 478U, 482U, 486U}; + 2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, 50U, 54U, 58U, 63U, 67U, 71U, 75U, 79U, 83U, + 87U, 91U, 95U, 99U, 103U, 107U, 111U, 115U, 119U, 124U, 128U, 132U, 136U, 140U, 144U, 148U, 152U, 156U, 160U, 164U, 168U, + 172U, 176U, 180U, 185U, 189U, 193U, 197U, 201U, 205U, 209U, 213U, 217U, 221U, 225U, 229U, 233U, 237U, 241U, 246U, 250U, 254U, + 258U, 262U, 266U, 270U, 274U, 278U, 282U, 286U, 290U, 294U, 298U, 302U, 307U, 311U, 315U, 319U, 323U, 327U, 331U, 335U, 339U, + 343U, 347U, 351U, 355U, 359U, 363U, 368U, 372U, 376U, 380U, 384U, 388U, 392U, 396U, 400U, 404U, 408U, 412U, 416U, 420U, 424U, + 429U, 433U, 437U, 441U, 445U, 449U, 453U, 457U, 461U, 465U, 469U, 473U, 477U, 481U, 485U}; const unsigned int PUNCTURE_LIST_DATA_COUNT = 12U; diff --git a/Version.h b/Version.h index 5e64e73..6f97089 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20210823"; +const char* VERSION = "20210905"; #endif From 0071fce5c077e5d6a913aba6f93c7a44075929d0 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 5 Sep 2021 16:19:05 +0100 Subject: [PATCH 10/11] Fix the calculation of the Link Setup BER. --- M17Convolution.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/M17Convolution.cpp b/M17Convolution.cpp index aa9226c..56e689d 100644 --- a/M17Convolution.cpp +++ b/M17Convolution.cpp @@ -23,7 +23,7 @@ #include #include -const unsigned int PUNCTURE_LIST_LINK_SETUP_COUNT = 61U; +const unsigned int PUNCTURE_LIST_LINK_SETUP_COUNT = 60U; const unsigned int PUNCTURE_LIST_LINK_SETUP[] = { 2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, 50U, 54U, 58U, 63U, 67U, 71U, 75U, 79U, 83U, From 6aac9d67b7b3215555f328ec69fdd5087fb47c87 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 5 Sep 2021 17:55:23 +0100 Subject: [PATCH 11/11] Document the AccessMode value for the FM repeater. --- MMDVM.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MMDVM.ini b/MMDVM.ini index 0e147ea..f687814 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -187,6 +187,11 @@ CTCSSThreshold=30 CTCSSLevel=20 KerchunkTime=0 HangTime=7 +# AccessMode values are: +# 0 - Carrier access with COS +# 1 - CTCSS only access without COS +# 2 - CTCSS only access with COS +# 3 - CTCSS only access with COS to start, then carrier access with COS AccessMode=1 COSInvert=0 NoiseSquelch=0