From dbf771d80c51c3469a9275de9afbc3346d119ebf Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 25 Mar 2021 21:07:44 +0000 Subject: [PATCH] Fixed M17 to be compatible with the latest protocol speciication. --- Conf.cpp | 10 +- Conf.h | 4 +- M17CRC.cpp | 2 +- M17Control.cpp | 396 ++++++++++++++++++++------------------ M17Control.h | 19 +- M17Convolution.cpp | 2 +- M17Convolution.h | 2 +- M17Defines.h | 25 ++- M17LICH.cpp | 143 -------------- M17LSF.cpp | 193 +++++++++++++++++++ M17LICH.h => M17LSF.h | 26 ++- M17Network.cpp | 2 +- M17Network.h | 2 +- M17Utils.cpp | 15 +- MMDVM.ini | 2 +- MMDVMHost.cpp | 6 +- MMDVMHost.vcxproj | 4 +- MMDVMHost.vcxproj.filters | 4 +- Makefile | 2 +- Makefile.Pi | 2 +- Makefile.Pi.Adafruit | 2 +- Makefile.Pi.HD44780 | 2 +- Makefile.Pi.OLED | 2 +- Makefile.Pi.PCF8574 | 2 +- Version.h | 2 +- 25 files changed, 481 insertions(+), 390 deletions(-) delete mode 100644 M17LICH.cpp create mode 100644 M17LSF.cpp rename M17LICH.h => M17LSF.h (73%) diff --git a/Conf.cpp b/Conf.cpp index 83d22f4..dcc9bc4 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -182,7 +182,7 @@ m_nxdnRemoteGateway(false), m_nxdnTXHang(5U), m_nxdnModeHang(10U), m_m17Enabled(false), -m_m17ColorCode(1U), +m_m17CAN(0U), m_m17SelfOnly(false), m_m17AllowEncryption(false), m_m17TXHang(5U), @@ -779,8 +779,8 @@ bool CConf::read() } else if (section == SECTION_M17) { if (::strcmp(key, "Enable") == 0) m_m17Enabled = ::atoi(value) == 1; - else if (::strcmp(key, "ColorCode") == 0) - m_m17ColorCode = (unsigned int)::atoi(value); + else if (::strcmp(key, "CAN") == 0) + m_m17CAN = (unsigned int)::atoi(value); else if (::strcmp(key, "SelfOnly") == 0) m_m17SelfOnly = ::atoi(value) == 1; else if (::strcmp(key, "AllowEncryption") == 0) @@ -1707,9 +1707,9 @@ bool CConf::getM17Enabled() const return m_m17Enabled; } -unsigned int CConf::getM17ColorCode() const +unsigned int CConf::getM17CAN() const { - return m_m17ColorCode; + return m_m17CAN; } bool CConf::getM17SelfOnly() const diff --git a/Conf.h b/Conf.h index aad1155..dc31ef5 100644 --- a/Conf.h +++ b/Conf.h @@ -173,7 +173,7 @@ public: // The M17 section bool getM17Enabled() const; - unsigned int getM17ColorCode() const; + unsigned int getM17CAN() const; bool getM17SelfOnly() const; bool getM17AllowEncryption() const; unsigned int getM17TXHang() const; @@ -496,7 +496,7 @@ private: unsigned int m_nxdnModeHang; bool m_m17Enabled; - unsigned int m_m17ColorCode; + unsigned int m_m17CAN; bool m_m17SelfOnly; bool m_m17AllowEncryption; unsigned int m_m17TXHang; diff --git a/M17CRC.cpp b/M17CRC.cpp index 7ba4da6..cd41697 100644 --- a/M17CRC.cpp +++ b/M17CRC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020 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 diff --git a/M17Control.cpp b/M17Control.cpp index a36d0eb..5ab306e 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2020 Jonathan Naylor, G4KLX + * Copyright (C) 2020,2021 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 @@ -57,9 +57,9 @@ const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04 #define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) -CM17Control::CM17Control(const std::string& callsign, unsigned int colorCode, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) : +CM17Control::CM17Control(const std::string& callsign, unsigned int can, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) : m_callsign(callsign), -m_colorCode(colorCode), +m_can(can), m_selfOnly(selfOnly), m_allowEncryption(allowEncryption), m_network(network), @@ -78,10 +78,10 @@ m_netFrames(0U), m_rfFN(0U), m_rfErrs(0U), m_rfBits(1U), -m_rfLICH(), -m_rfLICHn(0U), -m_netLICH(), -m_netLICHn(0U), +m_rfLSF(), +m_rfLSFn(0U), +m_netLSF(), +m_netLSFn(0U), m_rssiMapper(rssiMapper), m_rssi(0U), m_maxRSSI(0U), @@ -109,8 +109,8 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) unsigned char type = data[0U]; if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) { - std::string source = m_rfLICH.getSource(); - std::string dest = m_rfLICH.getDest(); + std::string source = m_rfLSF.getSource(); + std::string dest = m_rfLSF.getDest(); if (m_rssi != 0U) LogMessage("M17, transmission lost 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); @@ -125,6 +125,11 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) return false; } + if (type == TAG_LOST && m_rfState == RS_RF_REJECTED) { + writeEndRF(); + return false; + } + if (type == TAG_LOST) { m_rfState = RS_RF_LISTENING; return false; @@ -158,14 +163,22 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) interleaver(temp, data + 2U); if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_HEADER) { - m_rfLICH.reset(); + m_rfLSF.reset(); CM17Convolution conv; - unsigned char frame[M17_LICH_LENGTH_BYTES]; + unsigned char frame[M17_LSF_LENGTH_BYTES]; conv.decodeLinkSetup(data + 2U + M17_SYNC_LENGTH_BYTES, frame); - bool valid = CM17CRC::checkCRC(frame, M17_LICH_LENGTH_BYTES); + bool valid = CM17CRC::checkCRC(frame, M17_LSF_LENGTH_BYTES); if (valid) { + m_rfLSF.setLinkSetup(frame); + + bool ret = processRFHeader(false); + if (!ret) { + m_rfLSF.reset(); + return false; + } + m_rfFrames = 0U; m_rfErrs = 0U; m_rfBits = 1U; @@ -174,22 +187,23 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) m_maxRSSI = m_rssi; m_aveRSSI = m_rssi; m_rssiCount = 1U; - m_rfLICHn = 0U; + m_rfLSFn = 0U; m_rfFN = 0U; #if defined(DUMP_M17) openFile(); #endif - m_rfLICH.setLinkSetup(frame); - - m_rfState = RS_RF_LATE_ENTRY; - return true; } else { m_rfState = RS_RF_LATE_ENTRY; } } + if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_DATA) { + m_rfState = RS_RF_LATE_ENTRY; + m_rfLSF.reset(); + } + if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) { unsigned int frag1, frag2, frag3, frag4; CM17Utils::splitFragmentLICHFEC(data + 2U + M17_SYNC_LENGTH_BYTES, frag1, frag2, frag3, frag4); @@ -199,23 +213,24 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) unsigned int lich3 = CGolay24128::decode24128(frag3); unsigned int lich4 = CGolay24128::decode24128(frag4); - unsigned int colorCode = (lich4 >> 7) & 0x1FU; - if (colorCode != m_colorCode) + unsigned int can = lich4 & 0x1FU; + if (can != m_can) return false; - bool lateEntry = false; - if (!m_rfLICH.isValid()) { - unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; - CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich); + unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; + CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich); - unsigned int n = (lich4 >> 4) & 0x07U; - m_rfLICH.setFragment(lich, n); + m_rfLSFn = (lich4 >> 5) & 0x07U; + m_rfLSF.setFragment(lich, m_rfLSFn); - lateEntry = true; - } - - bool valid = m_rfLICH.isValid(); + bool valid = m_rfLSF.isValid(); if (valid) { + bool ret = processRFHeader(true); + if (!ret) { + m_rfLSF.reset(); + return false; + } + m_rfFrames = 0U; m_rfErrs = 0U; m_rfBits = 1U; @@ -224,68 +239,13 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) m_maxRSSI = m_rssi; m_aveRSSI = m_rssi; m_rssiCount = 1U; - m_rfLICHn = 0U; #if defined(DUMP_M17) openFile(); #endif - std::string source = m_rfLICH.getSource(); - std::string dest = m_rfLICH.getDest(); - - if (m_selfOnly) { - bool ret = checkCallsign(source); - if (!ret) { - LogMessage("M17, invalid access attempt from %s to %s", source.c_str(), dest.c_str()); - m_rfState = RS_RF_REJECTED; - return false; - } - } - - unsigned char dataType = m_rfLICH.getDataType(); - switch (dataType) { - case 1U: - LogMessage("M17, received RF %s data transmission from %s to %s", lateEntry ? "late entry" : "", source.c_str(), dest.c_str()); - m_rfState = RS_RF_DATA; - break; - case 2U: - LogMessage("M17, received RF %s voice transmission from %s to %s", lateEntry ? "late entry" : "", source.c_str(), dest.c_str()); - m_rfState = RS_RF_AUDIO; - break; - case 3U: - LogMessage("M17, received RF %s voice + data transmission from %s to %s", lateEntry ? "late entry" : "", source.c_str(), dest.c_str()); - m_rfState = RS_RF_AUDIO; - break; - default: - LogMessage("M17, received RF %s unknown transmission from %s to %s", lateEntry ? "late entry" : "", source.c_str(), dest.c_str()); - m_rfState = RS_RF_DATA; - break; - } - - m_display->writeM17(source.c_str(), dest.c_str(), "R"); - - if (m_duplex) { - // Create a Link Setup frame - data[0U] = TAG_HEADER; - data[1U] = 0x00U; - - // Generate the sync - CSync::addM17LinkSetupSync(data + 2U); - - unsigned char setup[M17_LICH_LENGTH_BYTES]; - m_rfLICH.getLinkSetup(setup); - - // Add the convolution FEC - CM17Convolution conv; - conv.encodeLinkSetup(setup, data + 2U + M17_SYNC_LENGTH_BYTES); - - unsigned char temp[M17_FRAME_LENGTH_BYTES]; - interleaver(data + 2U, temp); - decorrelator(temp, data + 2U); - - writeQueueRF(data); - } - - // Fall through to the next section + // Fall through + } else { + return false; } } @@ -309,13 +269,13 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) frame[1U] = m_rfFN >> 0; // Add silent audio - unsigned char dataType = m_rfLICH.getDataType(); + unsigned char dataType = m_rfLSF.getDataType(); switch (dataType) { - case 2U: + case M17_DATA_TYPE_VOICE: ::memcpy(frame + M17_FN_LENGTH_BYTES + 0U, M17_3200_SILENCE, 8U); ::memcpy(frame + M17_FN_LENGTH_BYTES + 8U, M17_3200_SILENCE, 8U); break; - case 3U: + case M17_DATA_TYPE_VOICE_DATA: ::memcpy(frame + M17_FN_LENGTH_BYTES + 0U, M17_1600_SILENCE, 8U); break; default: @@ -335,14 +295,14 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) CSync::addM17StreamSync(rfData + 2U); unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; - m_netLICH.getFragment(lich, m_rfLICHn); + m_rfLSF.getFragment(lich, m_rfLSFn); unsigned int frag1, frag2, frag3, frag4; CM17Utils::splitFragmentLICH(lich, frag1, frag2, frag3, frag4); - // Add the Color Code and fragment number - frag4 |= (m_rfLICHn & 0x07U) << 4; - frag4 |= (m_colorCode & 0x1FU) << 7; + // Add the CAN and fragment number + frag4 |= (m_rfLSFn & 0x07U) << 5; + frag4 |= m_can & 0x1FU; // Add Golay to the LICH fragment here unsigned int lich1 = CGolay24128::encode24128(frag1); @@ -361,7 +321,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) for (unsigned int i = 2U; i < (M17_FRAME_LENGTH_BYTES + 2U); i++) errors += countBits(rfData[i] ^ data[i]); - LogDebug("M17, FN: %u, errs: %u/384 (%.1f%%)", m_rfFN, errors, float(errors) / 3.84F); + LogDebug("M17, FN: %u, errs: %u/384 (%.1f%%)", m_rfFN & 0x7FU, errors, float(errors) / 3.84F); m_rfBits += M17_FRAME_LENGTH_BITS; m_rfErrs += errors; @@ -372,32 +332,34 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) unsigned char temp[M17_FRAME_LENGTH_BYTES]; interleaver(rfData + 2U, temp); - decorrelator(rfData, data + 2U); + decorrelator(temp, rfData + 2U); if (m_duplex) writeQueueRF(rfData); - unsigned char netData[M17_LICH_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; + 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_rfLICH.getNetwork(netData + 0U); + m_rfLSF.getNetwork(netData + 0U); - // Copy the FN and payload from the frame - ::memcpy(netData + M17_LICH_LENGTH_BYTES - M17_CRC_LENGTH_BYTES, frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); + // 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); - // The CRC is added in the networking code + // The CRC is added in the networking code - writeNetwork(netData); + m_network->write(netData); + } m_rfFrames++; - m_rfLICHn++; - if (m_rfLICHn >= 6U) - m_rfLICHn = 0U; + m_rfLSFn++; + if (m_rfLSFn >= 6U) + m_rfLSFn = 0U; // EOT? if ((m_rfFN & 0x8000U) == 0x8000U) { - std::string source = m_rfLICH.getSource(); - std::string dest = m_rfLICH.getDest(); + 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); @@ -409,22 +371,6 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) return true; } - if (m_rfState == RS_RF_REJECTED && data[0U] == TAG_DATA) { - CM17Convolution conv; - unsigned char frame[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; - conv.decodeData(data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES, frame); - - bool valid = CM17CRC::checkCRC(frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES); - if (valid) { - // Handle the EOT for rejected frames - unsigned int fn = (frame[0U] << 8) + (frame[1U] << 0); - if ((fn & 0x8000U) == 0x8000U) - writeEndRF(); - } - - return false; - } - return false; } @@ -449,7 +395,7 @@ void CM17Control::writeEndRF() m_rfTimeoutTimer.stop(); - m_rfLICH.reset(); + m_rfLSF.reset(); if (m_netState == RS_NET_IDLE) { m_display->clearM17(); @@ -471,7 +417,7 @@ void CM17Control::writeEndNet() m_networkWatchdog.stop(); m_packetTimer.stop(); - m_netLICH.reset(); + m_netLSF.reset(); m_display->clearM17(); @@ -494,29 +440,30 @@ void CM17Control::writeNetwork() m_networkWatchdog.start(); - m_netLICH.setNetwork(netData); + m_netLSF.setNetwork(netData); + m_netLSF.setCAN(m_can); if (!m_allowEncryption) { - bool ret = m_rfLICH.isNONCENull(); - if (!ret) + unsigned char type = m_netLSF.getEncryptionType(); + if (type != M17_ENCRYPTION_TYPE_NONE) return; } if (m_netState == RS_NET_IDLE) { - std::string source = m_netLICH.getSource(); - std::string dest = m_netLICH.getDest(); + std::string source = m_netLSF.getSource(); + std::string dest = m_netLSF.getDest(); - unsigned char dataType = m_netLICH.getDataType(); + unsigned char dataType = m_netLSF.getDataType(); switch (dataType) { - case 1U: + case M17_DATA_TYPE_DATA: LogMessage("M17, received network data transmission from %s to %s", source.c_str(), dest.c_str()); m_netState = RS_NET_DATA; break; - case 2U: + case M17_DATA_TYPE_VOICE: LogMessage("M17, received network voice transmission from %s to %s", source.c_str(), dest.c_str()); m_netState = RS_NET_AUDIO; break; - case 3U: + case M17_DATA_TYPE_VOICE_DATA: LogMessage("M17, received network voice + data transmission from %s to %s", source.c_str(), dest.c_str()); m_netState = RS_NET_AUDIO; break; @@ -532,7 +479,7 @@ void CM17Control::writeNetwork() m_packetTimer.start(); m_elapsed.start(); m_netFrames = 0U; - m_netLICHn = 0U; + m_netLSFn = 0U; // Create a dummy start message unsigned char start[M17_FRAME_LENGTH_BYTES + 2U]; @@ -543,8 +490,8 @@ void CM17Control::writeNetwork() // Generate the sync CSync::addM17LinkSetupSync(start + 2U); - unsigned char setup[M17_LICH_LENGTH_BYTES]; - m_netLICH.getLinkSetup(setup); + unsigned char setup[M17_LSF_LENGTH_BYTES]; + m_netLSF.getLinkSetup(setup); // Add the convolution FEC CM17Convolution conv; @@ -557,66 +504,144 @@ void CM17Control::writeNetwork() writeQueueNet(start); } - unsigned char data[M17_FRAME_LENGTH_BYTES + 2U]; + if (m_netState == RS_NET_AUDIO) { + unsigned char data[M17_FRAME_LENGTH_BYTES + 2U]; - data[0U] = TAG_DATA; - data[1U] = 0x00U; + data[0U] = TAG_DATA; + data[1U] = 0x00U; - // Generate the sync - CSync::addM17StreamSync(data + 2U); + // Generate the sync + CSync::addM17StreamSync(data + 2U); - m_netFrames++; + m_netFrames++; - // Add the fragment LICH - unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; - m_netLICH.getFragment(lich, m_netLICHn); + // Add the fragment LICH + unsigned char lich[M17_LSF_FRAGMENT_LENGTH_BYTES]; + m_netLSF.getFragment(lich, m_netLSFn); - unsigned int frag1, frag2, frag3, frag4; - CM17Utils::splitFragmentLICH(lich, frag1, frag2, frag3, frag4); + unsigned int frag1, frag2, frag3, frag4; + CM17Utils::splitFragmentLICH(lich, frag1, frag2, frag3, frag4); - // Add the Color Code and fragment number - frag4 |= (m_netLICHn & 0x07U) << 4; - frag4 |= (m_colorCode & 0x1FU) << 7; + // Add the Color Code and fragment number + frag4 |= (m_netLSFn & 0x07U) << 4; + frag4 |= (m_can & 0x1FU) << 7; - // Add Golay to the LICH fragment here - unsigned int lich1 = CGolay24128::encode24128(frag1); - unsigned int lich2 = CGolay24128::encode24128(frag2); - unsigned int lich3 = CGolay24128::encode24128(frag3); - unsigned int lich4 = CGolay24128::encode24128(frag4); + // Add Golay to the LICH fragment here + unsigned int lich1 = CGolay24128::encode24128(frag1); + unsigned int lich2 = CGolay24128::encode24128(frag2); + unsigned int lich3 = CGolay24128::encode24128(frag3); + unsigned int lich4 = CGolay24128::encode24128(frag4); - CM17Utils::combineFragmentLICHFEC(lich1, lich2, lich3, lich4, data + 2U + M17_SYNC_LENGTH_BYTES); + CM17Utils::combineFragmentLICHFEC(lich1, lich2, lich3, lich4, data + 2U + M17_SYNC_LENGTH_BYTES); - // Add the FN and the data/audio - unsigned char payload[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; - ::memcpy(payload, netData + 28U, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); + // Add the FN and the data/audio + unsigned char payload[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; + ::memcpy(payload, netData + 28U, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); - // Add the CRC - CM17CRC::encodeCRC(payload, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES); + // Add the CRC + CM17CRC::encodeCRC(payload, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES); - // Add the Convolution FEC - CM17Convolution conv; - conv.encodeData(payload, data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES); + // Add the Convolution FEC + CM17Convolution conv; + conv.encodeData(payload, data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES); - unsigned char temp[M17_FRAME_LENGTH_BYTES]; - interleaver(data + 2U, temp); - decorrelator(temp, data + 2U); + unsigned char temp[M17_FRAME_LENGTH_BYTES]; + interleaver(data + 2U, temp); + decorrelator(temp, data + 2U); - writeQueueNet(data); + writeQueueNet(data); - m_netLICHn++; - if (m_netLICHn >= 6U) - m_netLICHn = 0U; + m_netLSFn++; + if (m_netLSFn >= 6U) + m_netLSFn = 0U; - // EOT handling - uint16_t fn = (netData[28U] << 8) + (netData[29U] << 0); - if ((fn & 0x8000U) == 0x8000U) { - std::string source = m_netLICH.getSource(); - std::string dest = m_netLICH.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); - writeEndNet(); + // EOT handling + uint16_t fn = (netData[28U] << 8) + (netData[29U] << 0); + 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); + writeEndNet(); + } } } +bool CM17Control::processRFHeader(bool lateEntry) +{ + unsigned char can = m_rfLSF.getCAN(); + if (can != m_can) + return false; + + std::string source = m_rfLSF.getSource(); + std::string dest = m_rfLSF.getDest(); + + if (!m_allowEncryption) { + unsigned char type = m_rfLSF.getEncryptionType(); + if (type != M17_ENCRYPTION_TYPE_NONE) { + LogMessage("M17, access attempt with encryption from %s to %s", source.c_str(), dest.c_str()); + m_rfState = RS_RF_REJECTED; + return false; + } + } + + if (m_selfOnly) { + bool ret = checkCallsign(source); + if (!ret) { + LogMessage("M17, invalid access attempt from %s to %s", source.c_str(), dest.c_str()); + m_rfState = RS_RF_REJECTED; + return false; + } + } + + unsigned char dataType = m_rfLSF.getDataType(); + switch (dataType) { + case M17_DATA_TYPE_DATA: + LogMessage("M17, received RF%sdata transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str()); + m_rfState = RS_RF_DATA; + break; + case M17_DATA_TYPE_VOICE: + LogMessage("M17, received RF%svoice transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str()); + m_rfState = RS_RF_AUDIO; + break; + case M17_DATA_TYPE_VOICE_DATA: + LogMessage("M17, received RF%svoice + data transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str()); + m_rfState = RS_RF_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; + } + + m_display->writeM17(source.c_str(), dest.c_str(), "R"); + + if (m_duplex) { + unsigned char data[M17_FRAME_LENGTH_BYTES + 2U]; + + // Create a Link Setup frame + data[0U] = TAG_HEADER; + data[1U] = 0x00U; + + // Generate the sync + CSync::addM17LinkSetupSync(data + 2U); + + unsigned char setup[M17_LSF_LENGTH_BYTES]; + m_rfLSF.getLinkSetup(setup); + + // Add the convolution FEC + CM17Convolution conv; + conv.encodeLinkSetup(setup, data + 2U + M17_SYNC_LENGTH_BYTES); + + unsigned char temp[M17_FRAME_LENGTH_BYTES]; + interleaver(data + 2U, temp); + decorrelator(temp, data + 2U); + + writeQueueRF(data); + } + + return true; +} + void CM17Control::clock(unsigned int ms) { if (m_network != NULL) @@ -678,19 +703,6 @@ void CM17Control::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CM17Control::writeNetwork(const unsigned char *data) -{ - assert(data != NULL); - - if (m_network == NULL) - return; - - if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired()) - return; - - m_network->write(data); -} - void CM17Control::interleaver(const unsigned char* in, unsigned char* out) const { assert(in != NULL); diff --git a/M17Control.h b/M17Control.h index 276478c..9ed515c 100644 --- a/M17Control.h +++ b/M17Control.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021 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 @@ -24,9 +24,9 @@ #include "M17Defines.h" #include "RingBuffer.h" #include "StopWatch.h" -#include "M17LICH.h" #include "Display.h" #include "Defines.h" +#include "M17LSF.h" #include "Timer.h" #include "Modem.h" @@ -34,7 +34,7 @@ class CM17Control { public: - CM17Control(const std::string& callsign, unsigned int colorCode, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper); + CM17Control(const std::string& callsign, unsigned int can, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper); ~CM17Control(); bool writeModem(unsigned char* data, unsigned int len); @@ -49,7 +49,7 @@ public: private: std::string m_callsign; - unsigned int m_colorCode; + unsigned int m_can; bool m_selfOnly; bool m_allowEncryption; CM17Network* m_network; @@ -68,10 +68,10 @@ private: unsigned int m_rfFN; unsigned int m_rfErrs; unsigned int m_rfBits; - CM17LICH m_rfLICH; - unsigned int m_rfLICHn; - CM17LICH m_netLICH; - unsigned int m_netLICHn; + CM17LSF m_rfLSF; + unsigned int m_rfLSFn; + CM17LSF m_netLSF; + unsigned int m_netLSFn; CRSSIInterpolator* m_rssiMapper; unsigned char m_rssi; unsigned char m_maxRSSI; @@ -81,9 +81,10 @@ private: bool m_enabled; FILE* m_fp; + bool processRFHeader(bool lateEntry); + void writeQueueRF(const unsigned char* data); void writeQueueNet(const unsigned char* data); - void writeNetwork(const unsigned char* data); void writeNetwork(); void interleaver(const unsigned char* in, unsigned char* out) const; diff --git a/M17Convolution.cpp b/M17Convolution.cpp index 1f64a76..5a83ab0 100644 --- a/M17Convolution.cpp +++ b/M17Convolution.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016,2018,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020 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 diff --git a/M17Convolution.h b/M17Convolution.h index e3f5d82..91843ba 100644 --- a/M17Convolution.h +++ b/M17Convolution.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2018,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020 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 diff --git a/M17Defines.h b/M17Defines.h index 2eae167..5dc07f7 100644 --- a/M17Defines.h +++ b/M17Defines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021 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 @@ -31,12 +31,18 @@ const unsigned char M17_PACKET_SYNC_BYTES[] = {0x75U, 0xFFU}; const unsigned int M17_SYNC_LENGTH_BITS = 16U; const unsigned int M17_SYNC_LENGTH_BYTES = M17_SYNC_LENGTH_BITS / 8U; -const unsigned int M17_LICH_LENGTH_BITS = 240U; -const unsigned int M17_LICH_LENGTH_BYTES = M17_LICH_LENGTH_BITS / 8U; +const unsigned int M17_LSF_LENGTH_BITS = 240U; +const unsigned int M17_LSF_LENGTH_BYTES = M17_LSF_LENGTH_BITS / 8U; -const unsigned int M17_LICH_FRAGMENT_LENGTH_BITS = M17_LICH_LENGTH_BITS / 6U; +const unsigned int M17_LSF_FRAGMENT_LENGTH_BITS = M17_LSF_LENGTH_BITS / 6U; +const unsigned int M17_LSF_FRAGMENT_LENGTH_BYTES = M17_LSF_FRAGMENT_LENGTH_BITS / 8U; + +const unsigned int M17_LICH_FRAGMENT_LENGTH_BITS = M17_LSF_FRAGMENT_LENGTH_BITS + 8U; const unsigned int M17_LICH_FRAGMENT_LENGTH_BYTES = M17_LICH_FRAGMENT_LENGTH_BITS / 8U; +const unsigned int M17_LSF_FRAGMENT_FEC_LENGTH_BITS = M17_LSF_FRAGMENT_LENGTH_BITS * 2U; +const unsigned int M17_LSF_FRAGMENT_FEC_LENGTH_BYTES = M17_LSF_FRAGMENT_FEC_LENGTH_BITS / 8U; + const unsigned int M17_LICH_FRAGMENT_FEC_LENGTH_BITS = M17_LICH_FRAGMENT_LENGTH_BITS * 2U; const unsigned int M17_LICH_FRAGMENT_FEC_LENGTH_BYTES = M17_LICH_FRAGMENT_FEC_LENGTH_BITS / 8U; @@ -56,4 +62,15 @@ 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_PACKET_TYPE = 0U; +const unsigned char M17_STREAM_TYPE = 1U; + +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; + +const unsigned char M17_ENCRYPTION_TYPE_NONE = 0x00U; +const unsigned char M17_ENCRYPTION_TYPE_AES = 0x01U; +const unsigned char M17_ENCRYPTION_TYPE_SCRAMBLE = 0x02U; + #endif diff --git a/M17LICH.cpp b/M17LICH.cpp deleted file mode 100644 index e99fd8d..0000000 --- a/M17LICH.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2020 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "M17LICH.h" -#include "M17Utils.h" -#include "M17Defines.h" -#include "M17CRC.h" - -#include -#include - -CM17LICH::CM17LICH() : -m_lich(NULL), -m_valid(false) -{ - m_lich = new unsigned char[M17_LICH_LENGTH_BYTES]; -} - -CM17LICH::~CM17LICH() -{ - delete[] m_lich; -} - -void CM17LICH::getNetwork(unsigned char* data) const -{ - assert(data != NULL); - - ::memcpy(data, m_lich, M17_LICH_LENGTH_BYTES); -} - -void CM17LICH::setNetwork(const unsigned char* data) -{ - assert(data != NULL); - - ::memcpy(m_lich, data, M17_LICH_LENGTH_BYTES); - - m_valid = true; -} - -std::string CM17LICH::getSource() const -{ - std::string callsign; - CM17Utils::decodeCallsign(m_lich + 6U, callsign); - - return callsign; -} - -void CM17LICH::setSource(const std::string& callsign) -{ - CM17Utils::encodeCallsign(callsign, m_lich + 6U); -} - -std::string CM17LICH::getDest() const -{ - std::string callsign; - CM17Utils::decodeCallsign(m_lich + 0U, callsign); - - return callsign; -} - -void CM17LICH::setDest(const std::string& callsign) -{ - CM17Utils::encodeCallsign(callsign, m_lich + 0U); -} - -unsigned char CM17LICH::getDataType() const -{ - return (m_lich[13U] >> 1) & 0x03U; -} - -void CM17LICH::setDataType(unsigned char type) -{ - m_lich[13U] &= 0xF9U; - m_lich[13U] |= (type << 1) & 0x06U; -} - -bool CM17LICH::isNONCENull() const -{ - return ::memcmp(m_lich + 14U, M17_NULL_NONCE, M17_NONCE_LENGTH_BYTES) == 0; -} - -void CM17LICH::reset() -{ - ::memset(m_lich, 0x00U, 30U); - - m_valid = false; -} - -bool CM17LICH::isValid() const -{ - return m_valid; -} - -void CM17LICH::getLinkSetup(unsigned char* data) const -{ - assert(data != NULL); - - ::memcpy(data, m_lich, M17_LICH_LENGTH_BYTES); - - CM17CRC::encodeCRC(data, M17_LICH_LENGTH_BYTES); -} - -void CM17LICH::setLinkSetup(const unsigned char* data) -{ - assert(data != NULL); - - ::memcpy(m_lich, data, M17_LICH_LENGTH_BYTES); - - m_valid = CM17CRC::checkCRC(m_lich, M17_LICH_LENGTH_BYTES); -} - -void CM17LICH::getFragment(unsigned char* data, unsigned int n) const -{ - assert(data != NULL); - - CM17CRC::encodeCRC(m_lich, M17_LICH_LENGTH_BYTES); - - ::memcpy(data, m_lich + (n * M17_LICH_FRAGMENT_LENGTH_BYTES), M17_LICH_FRAGMENT_LENGTH_BYTES); -} - -void CM17LICH::setFragment(const unsigned char* data, unsigned int n) -{ - assert(data != NULL); - - ::memcpy(m_lich + (n * M17_LICH_FRAGMENT_LENGTH_BYTES), data, M17_LICH_FRAGMENT_LENGTH_BYTES); - - m_valid = CM17CRC::checkCRC(m_lich, M17_LICH_LENGTH_BYTES); -} diff --git a/M17LSF.cpp b/M17LSF.cpp new file mode 100644 index 0000000..4d48f40 --- /dev/null +++ b/M17LSF.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020,2021 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "M17LSF.h" +#include "M17Utils.h" +#include "M17Defines.h" +#include "M17CRC.h" + +#include +#include + +CM17LSF::CM17LSF() : +m_lsf(NULL), +m_valid(false) +{ + m_lsf = new unsigned char[M17_LSF_LENGTH_BYTES]; +} + +CM17LSF::~CM17LSF() +{ + delete[] m_lsf; +} + +void CM17LSF::getNetwork(unsigned char* data) const +{ + assert(data != NULL); + + ::memcpy(data, m_lsf, M17_LSF_LENGTH_BYTES); +} + +void CM17LSF::setNetwork(const unsigned char* data) +{ + assert(data != NULL); + + ::memcpy(m_lsf, data, M17_LSF_LENGTH_BYTES); + + m_valid = true; +} + +std::string CM17LSF::getSource() const +{ + if (m_lsf[6U] == 0xFFU && m_lsf[7U] == 0xFFU && m_lsf[8U] == 0xFFU && + m_lsf[9U] == 0xFFU && m_lsf[10U] == 0xFFU && m_lsf[11U] == 0xFFU) + return "******"; + + std::string callsign; + CM17Utils::decodeCallsign(m_lsf + 6U, callsign); + + return callsign; +} + +void CM17LSF::setSource(const std::string& callsign) +{ + CM17Utils::encodeCallsign(callsign, m_lsf + 6U); +} + +std::string CM17LSF::getDest() const +{ + if (m_lsf[0U] == 0xFFU && m_lsf[1U] == 0xFFU && m_lsf[2U] == 0xFFU && + m_lsf[3U] == 0xFFU && m_lsf[4U] == 0xFFU && m_lsf[5U] == 0xFFU) + return "******"; + + std::string callsign; + CM17Utils::decodeCallsign(m_lsf + 0U, callsign); + + return callsign; +} + +void CM17LSF::setDest(const std::string& callsign) +{ + CM17Utils::encodeCallsign(callsign, m_lsf + 0U); +} + +unsigned char CM17LSF::getPacketStream() const +{ + return m_lsf[13U] & 0x01U; +} + +void CM17LSF::setPacketStream(unsigned char ps) +{ + m_lsf[13U] &= 0xF7U; + m_lsf[13U] |= ps & 0x01U; +} + +unsigned char CM17LSF::getDataType() const +{ + return (m_lsf[13U] >> 1) & 0x03U; +} + +void CM17LSF::setDataType(unsigned char type) +{ + m_lsf[13U] &= 0xF9U; + m_lsf[13U] |= (type << 1) & 0x06U; +} + +unsigned char CM17LSF::getEncryptionType() const +{ + return (m_lsf[13U] >> 3) & 0x03U; +} + +void CM17LSF::setEncryptionType(unsigned char type) +{ + m_lsf[13U] &= 0xE7U; + m_lsf[13U] |= (type << 3) & 0x18U; +} + +unsigned char CM17LSF::getEncryptionSubType() const +{ + return (m_lsf[13U] >> 5) & 0x03U; +} + +void CM17LSF::setEncryptionSubType(unsigned char type) +{ + m_lsf[13U] &= 0x9FU; + m_lsf[13U] |= (type << 5) & 0x60U; +} + +unsigned char CM17LSF::getCAN() const +{ + return ((m_lsf[12U] << 1) & 0x0EU) | ((m_lsf[13U] >> 7) & 0x01U); +} + +void CM17LSF::setCAN(unsigned char can) +{ + m_lsf[13U] &= 0x7FU; + m_lsf[13U] |= (can << 7) & 0x80U; + + m_lsf[12U] &= 0xF8U; + m_lsf[12U] |= (can >> 1) & 0x07U; +} + +void CM17LSF::reset() +{ + ::memset(m_lsf, 0x00U, 30U); + + m_valid = false; +} + +bool CM17LSF::isValid() const +{ + return m_valid; +} + +void CM17LSF::getLinkSetup(unsigned char* data) const +{ + assert(data != NULL); + + ::memcpy(data, m_lsf, M17_LSF_LENGTH_BYTES); + + CM17CRC::encodeCRC(data, M17_LSF_LENGTH_BYTES); +} + +void CM17LSF::setLinkSetup(const unsigned char* data) +{ + assert(data != NULL); + + ::memcpy(m_lsf, data, M17_LSF_LENGTH_BYTES); + + m_valid = CM17CRC::checkCRC(m_lsf, M17_LSF_LENGTH_BYTES); +} + +void CM17LSF::getFragment(unsigned char* data, unsigned int n) const +{ + assert(data != NULL); + + CM17CRC::encodeCRC(m_lsf, M17_LSF_LENGTH_BYTES); + + ::memcpy(data, m_lsf + (n * M17_LSF_FRAGMENT_LENGTH_BYTES), M17_LSF_FRAGMENT_LENGTH_BYTES); +} + +void CM17LSF::setFragment(const unsigned char* data, unsigned int n) +{ + assert(data != NULL); + + ::memcpy(m_lsf + (n * M17_LSF_FRAGMENT_LENGTH_BYTES), data, M17_LSF_FRAGMENT_LENGTH_BYTES); + + m_valid = CM17CRC::checkCRC(m_lsf, M17_LSF_LENGTH_BYTES); +} diff --git a/M17LICH.h b/M17LSF.h similarity index 73% rename from M17LICH.h rename to M17LSF.h index 804de3e..a12c1fe 100644 --- a/M17LICH.h +++ b/M17LSF.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021 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 @@ -16,15 +16,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined(M17LICH_H) -#define M17LICH_H +#if !defined(M17LSF_H) +#define M17LSF_H #include -class CM17LICH { +class CM17LSF { public: - CM17LICH(); - ~CM17LICH(); + CM17LSF(); + ~CM17LSF(); void getNetwork(unsigned char* data) const; void setNetwork(const unsigned char* data); @@ -35,10 +35,20 @@ public: std::string getDest() const; void setDest(const std::string& callsign); + unsigned char getPacketStream() const; + void setPacketStream(unsigned char ps); + unsigned char getDataType() const; void setDataType(unsigned char type); - bool isNONCENull() const; + unsigned char getEncryptionType() const; + void setEncryptionType(unsigned char type); + + unsigned char getEncryptionSubType() const; + void setEncryptionSubType(unsigned char type); + + unsigned char getCAN() const; + void setCAN(unsigned char can); void reset(); bool isValid() const; @@ -50,7 +60,7 @@ public: void setFragment(const unsigned char* data, unsigned int n); private: - unsigned char* m_lich; + unsigned char* m_lsf; bool m_valid; }; diff --git a/M17Network.cpp b/M17Network.cpp index 56a2135..2fd213d 100644 --- a/M17Network.cpp +++ b/M17Network.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016,2019,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020 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 diff --git a/M17Network.h b/M17Network.h index e65e1f3..9fc555a 100644 --- a/M17Network.h +++ b/M17Network.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016,2018,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020 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 diff --git a/M17Utils.cpp b/M17Utils.cpp index 1ba33b1..5a22adf 100644 --- a/M17Utils.cpp +++ b/M17Utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021 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 @@ -60,12 +60,13 @@ void CM17Utils::decodeCallsign(const unsigned char* encoded, std::string& callsi callsign.clear(); - uint64_t enc = (uint64_t(encoded[0U]) << 40) + - (uint64_t(encoded[1U]) << 32) + - (uint64_t(encoded[2U]) << 24) + - (uint64_t(encoded[3U]) << 16) + - (uint64_t(encoded[4U]) << 8) + - (uint64_t(encoded[5U]) << 0); + uint64_t enc = + (uint64_t(encoded[0U]) << 40) + + (uint64_t(encoded[1U]) << 32) + + (uint64_t(encoded[2U]) << 24) + + (uint64_t(encoded[3U]) << 16) + + (uint64_t(encoded[4U]) << 8) + + (uint64_t(encoded[5U]) << 0); if (enc >= 262144000000000ULL) // 40^9 return; diff --git a/MMDVM.ini b/MMDVM.ini index be1dbcf..b4fe1e1 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -149,7 +149,7 @@ TXHang=5 [M17] Enable=1 -ColorCode=3 +CAN=0 SelfOnly=0 TXHang=5 # ModeHang=10 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 592531a..b21870a 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -634,19 +634,19 @@ int CMMDVMHost::run() if (m_m17Enabled) { bool selfOnly = m_conf.getM17SelfOnly(); - unsigned int colorCode = m_conf.getM17ColorCode(); + unsigned int can = m_conf.getM17CAN(); bool allowEncryption = m_conf.getM17AllowEncryption(); unsigned int txHang = m_conf.getM17TXHang(); m_m17RFModeHang = m_conf.getM17ModeHang(); LogInfo("M17 RF Parameters"); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); - LogInfo(" Color Code: %u", colorCode); + LogInfo(" CAN: %u", can); LogInfo(" Allow Encryption: %s", allowEncryption ? "yes" : "no"); LogInfo(" TX Hang: %us", txHang); LogInfo(" Mode Hang: %us", m_m17RFModeHang); - m_m17 = new CM17Control(m_callsign, colorCode, selfOnly, allowEncryption, m_m17Network, m_display, m_timeout, m_duplex, rssi); + m_m17 = new CM17Control(m_callsign, can, selfOnly, allowEncryption, m_m17Network, m_display, m_timeout, m_duplex, rssi); } CTimer pocsagTimer(1000U, 30U); diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 182f62a..bebf213 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -199,7 +199,7 @@ - + @@ -308,7 +308,7 @@ - + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index 36320cd..77f0c68 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -296,7 +296,7 @@ Header Files - + Header Files @@ -610,7 +610,7 @@ Source Files - + Source Files diff --git a/Makefile b/Makefile index 901697a..fa6b777 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ OBJECTS = \ AMBEFEC.o BCH.o AX25Control.o AX25Network.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \ DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \ DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o Golay2087.o Golay24128.o \ - Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LICH.o M17Network.o M17Utils.o MMDVMHost.o \ + Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LSF.o M17Network.o M17Utils.o MMDVMHost.o \ Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o NXDNAudio.o NXDNControl.o \ NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o \ NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o PseudoTTYController.o POCSAGControl.o \ diff --git a/Makefile.Pi b/Makefile.Pi index 528c972..c0ab7f6 100644 --- a/Makefile.Pi +++ b/Makefile.Pi @@ -10,7 +10,7 @@ OBJECTS = \ AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \ DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \ DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o Golay2087.o Golay24128.o \ - Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LICH.o M17Network.o M17Utils.o MMDVMHost.o \ + Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LSF.o M17Network.o M17Utils.o MMDVMHost.o \ Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o NXDNAudio.o NXDNControl.o \ NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o \ NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o PseudoTTYController.o POCSAGControl.o \ diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index d4e75dd..a0538a1 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -11,7 +11,7 @@ OBJECTS = \ AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \ DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \ DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o Golay2087.o Golay24128.o \ - Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LICH.o M17Network.o M17Utils.o \ + Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LSF.o M17Network.o M17Utils.o \ MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o NXDNAudio.o \ NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o \ NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o PseudoTTYController.o \ diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 215d9f1..3885dc3 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -10,7 +10,7 @@ OBJECTS = \ AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \ DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \ DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o Golay2087.o Golay24128.o \ - Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LICH.o M17Network.o M17Utils.o \ + Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LSF.o M17Network.o M17Utils.o \ MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o NXDNAudio.o \ NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o \ NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o PseudoTTYController.o \ diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 889c72d..ab99eb2 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -14,7 +14,7 @@ OBJECTS = \ AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \ DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \ DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o Golay2087.o Golay24128.o \ - Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LICH.o M17Network.o M17Utils.o MMDVMHost.o \ + Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LSF.o M17Network.o M17Utils.o MMDVMHost.o \ Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o NXDNAudio.o NXDNControl.o \ NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o \ NXDNUDCH.o OLED.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o PseudoTTYController.o \ diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index ce09839..2fff7d9 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -11,7 +11,7 @@ OBJECTS = \ AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \ DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \ DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o Golay2087.o Golay24128.o \ - Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LICH.o M17Network.o M17Utils.o \ + Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o M17LSF.o M17Network.o M17Utils.o \ MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o NXDNAudio.o \ NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o \ NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o PseudoTTYController.o \ diff --git a/Version.h b/Version.h index 028594f..31bfcac 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20210314"; +const char* VERSION = "20210325"; #endif