diff --git a/Conf.cpp b/Conf.cpp index eed5d52..3aa5cd2 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -172,6 +172,7 @@ m_nxdnRemoteGateway(false), m_nxdnTXHang(5U), m_nxdnModeHang(10U), m_m17Enabled(false), +m_m17ColorCode(1U), m_m17SelfOnly(false), m_m17AllowEncryption(false), m_m17TXHang(5U), @@ -740,6 +741,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, "SelfOnly") == 0) m_m17SelfOnly = ::atoi(value) == 1; else if (::strcmp(key, "AllowEncryption") == 0) @@ -1606,6 +1609,11 @@ bool CConf::getM17Enabled() const return m_m17Enabled; } +unsigned int CConf::getM17ColorCode() const +{ + return m_m17ColorCode; +} + bool CConf::getM17SelfOnly() const { return m_m17SelfOnly; diff --git a/Conf.h b/Conf.h index 77b34b4..26bee7d 100644 --- a/Conf.h +++ b/Conf.h @@ -163,6 +163,7 @@ public: // The M17 section bool getM17Enabled() const; + unsigned int getM17ColorCode() const; bool getM17SelfOnly() const; bool getM17AllowEncryption() const; unsigned int getM17TXHang() const; @@ -470,6 +471,7 @@ private: unsigned int m_nxdnModeHang; bool m_m17Enabled; + unsigned int m_m17ColorCode; bool m_m17SelfOnly; bool m_m17AllowEncryption; unsigned int m_m17TXHang; diff --git a/M17Control.cpp b/M17Control.cpp index 9a9f359..9be8607 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -57,8 +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, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) : +CM17Control::CM17Control(const std::string& callsign, unsigned int colorCode, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) : m_callsign(callsign), +m_colorCode(colorCode), m_selfOnly(selfOnly), m_allowEncryption(allowEncryption), m_network(network), @@ -78,7 +79,9 @@ m_rfFN(0U), m_rfErrs(0U), m_rfBits(1U), m_rfLICH(), +m_rfLICHn(0U), m_netLICH(), +m_netLICHn(0U), m_rssiMapper(rssiMapper), m_rssi(0U), m_maxRSSI(0U), @@ -154,7 +157,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) decorrelator(data + 2U, temp); interleaver(temp, data + 2U); - if (m_rfState == RS_RF_LISTENING) { + if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_HEADER) { m_rfLICH.reset(); CM17Convolution conv; @@ -171,13 +174,61 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) m_maxRSSI = m_rssi; m_aveRSSI = m_rssi; m_rssiCount = 1U; - m_rfFN = 0U; + m_rfLICHn = 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_LATE_ENTRY && data[0U] == TAG_DATA) { + unsigned int frag1, frag2, frag3, frag4; + CM17Utils::splitFragmentLICHFEC(data + 2U + M17_SYNC_LENGTH_BYTES, frag1, frag2, frag3, frag4); + + unsigned int lich1 = CGolay24128::decode24128(frag1); + unsigned int lich2 = CGolay24128::decode24128(frag2); + unsigned int lich3 = CGolay24128::decode24128(frag3); + unsigned int lich4 = CGolay24128::decode24128(frag4); + + unsigned int colorCode = (lich4 >> 7) & 0x1FU; + if (colorCode != m_colorCode) + 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 int n = (lich4 >> 4) & 0x07U; + m_rfLICH.setFragment(lich, n); + + lateEntry = true; + } + + bool valid = m_rfLICH.isValid(); + if (valid) { + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_minRSSI = m_rssi; + 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(); @@ -190,47 +241,36 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) } } - if (!m_allowEncryption) { - bool ret = m_rfLICH.isNONCENull(); - 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 data transmission from %s to %s", source.c_str(), dest.c_str()); + 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 voice transmission from %s to %s", source.c_str(), dest.c_str()); + 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 voice + data transmission from %s to %s", source.c_str(), dest.c_str()); + 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 unknown transmission from %s to %s", source.c_str(), dest.c_str()); + 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 defined(DUMP_M17) - writeFile(data + 2U); -#endif if (m_duplex) { - data[0U] = TAG_DATA; + // Create a Link Setup frame + data[0U] = TAG_HEADER; data[1U] = 0x00U; // Generate the sync - CSync::addM17Sync(data + 2U); - + CSync::addM17HeaderSync(data + 2U); + unsigned char setup[M17_LICH_LENGTH_BYTES]; m_rfLICH.getLinkSetup(setup); @@ -245,110 +285,11 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) writeQueueRF(data); } - return true; - } else { - m_rfState = RS_RF_LATE_ENTRY; + // Fall through to the next section } } - if (m_rfState == RS_RF_LATE_ENTRY) { - 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) { - m_rfFN = (frame[0U] << 8) + (frame[1U] << 0); - - unsigned int frag1, frag2, frag3, frag4; - CM17Utils::splitFragmentLICHFEC(data + 2U + M17_SYNC_LENGTH_BYTES, frag1, frag2, frag3, frag4); - - unsigned int lich1 = CGolay24128::decode24128(frag1); - unsigned int lich2 = CGolay24128::decode24128(frag2); - unsigned int lich3 = CGolay24128::decode24128(frag3); - unsigned int lich4 = CGolay24128::decode24128(frag4); - - unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; - CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich); - - m_rfLICH.setFragment(lich, m_rfFN); - - valid = m_rfLICH.isValid(); - if (valid) { - m_rfFrames = 0U; - m_rfErrs = 0U; - m_rfBits = 1U; - m_rfTimeoutTimer.start(); - m_minRSSI = m_rssi; - m_maxRSSI = m_rssi; - m_aveRSSI = m_rssi; - m_rssiCount = 1U; - -#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 late entry data transmission from %s to %s", source.c_str(), dest.c_str()); - m_rfState = RS_RF_DATA; - break; - case 2U: - LogMessage("M17, received RF late entry voice transmission from %s to %s", source.c_str(), dest.c_str()); - m_rfState = RS_RF_AUDIO; - break; - case 3U: - LogMessage("M17, received RF late entry voice + data transmission from %s to %s", source.c_str(), dest.c_str()); - m_rfState = RS_RF_AUDIO; - break; - default: - LogMessage("M17, received RF late entry unknown transmission from %s to %s", 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_DATA; - data[1U] = 0x00U; - - // Generate the sync - CSync::addM17Sync(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 - } - } - } - - if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) { + if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) && data[0U] == TAG_DATA) { #if defined(DUMP_M17) writeFile(data + 2U); #endif @@ -391,14 +332,18 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) rfData[1U] = 0x00U; // Generate the sync - CSync::addM17Sync(rfData + 2U); + CSync::addM17DataSync(rfData + 2U); unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; - m_netLICH.getFragment(lich, m_rfFN); + m_netLICH.getFragment(lich, m_rfLICHn); 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 Golay to the LICH fragment here unsigned int lich1 = CGolay24128::encode24128(frag1); unsigned int lich2 = CGolay24128::encode24128(frag2); @@ -445,6 +390,10 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) m_rfFrames++; + m_rfLICHn++; + if (m_rfLICHn >= 6U) + m_rfLICHn = 0U; + // EOT? if ((m_rfFN & 0x8000U) == 0x8000U) { std::string source = m_rfLICH.getSource(); @@ -460,7 +409,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) return true; } - if (m_rfState == RS_RF_REJECTED) { + 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); @@ -500,6 +449,8 @@ void CM17Control::writeEndRF() m_rfTimeoutTimer.stop(); + m_rfLICH.reset(); + if (m_netState == RS_NET_IDLE) { m_display->clearM17(); @@ -520,6 +471,8 @@ void CM17Control::writeEndNet() m_networkWatchdog.stop(); m_packetTimer.stop(); + m_netLICH.reset(); + m_display->clearM17(); if (m_network != NULL) @@ -579,15 +532,16 @@ void CM17Control::writeNetwork() m_packetTimer.start(); m_elapsed.start(); m_netFrames = 0U; + m_netLICHn = 0U; // Create a dummy start message unsigned char start[M17_FRAME_LENGTH_BYTES + 2U]; - start[0U] = TAG_DATA; + start[0U] = TAG_HEADER; start[1U] = 0x00U; // Generate the sync - CSync::addM17Sync(start + 2U); + CSync::addM17HeaderSync(start + 2U); unsigned char setup[M17_LICH_LENGTH_BYTES]; m_netLICH.getLinkSetup(setup); @@ -609,19 +563,21 @@ void CM17Control::writeNetwork() data[1U] = 0x00U; // Generate the sync - CSync::addM17Sync(data + 2U); + CSync::addM17DataSync(data + 2U); m_netFrames++; // Add the fragment LICH - uint16_t fn = (netData[28U] << 8) + (netData[29U] << 0); - unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES]; - m_netLICH.getFragment(lich, fn); + m_netLICH.getFragment(lich, m_netLICHn); 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 Golay to the LICH fragment here unsigned int lich1 = CGolay24128::encode24128(frag1); unsigned int lich2 = CGolay24128::encode24128(frag2); @@ -647,7 +603,12 @@ void CM17Control::writeNetwork() writeQueueNet(data); + m_netLICHn++; + if (m_netLICHn >= 6U) + m_netLICHn = 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(); diff --git a/M17Control.h b/M17Control.h index bff2d19..276478c 100644 --- a/M17Control.h +++ b/M17Control.h @@ -34,7 +34,7 @@ class CM17Control { public: - CM17Control(const std::string& callsign, bool selfOnly, bool allowEncryption, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper); + CM17Control(const std::string& callsign, unsigned int colorCode, 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,6 +49,7 @@ public: private: std::string m_callsign; + unsigned int m_colorCode; bool m_selfOnly; bool m_allowEncryption; CM17Network* m_network; @@ -68,7 +69,9 @@ private: unsigned int m_rfErrs; unsigned int m_rfBits; CM17LICH m_rfLICH; + unsigned int m_rfLICHn; CM17LICH m_netLICH; + unsigned int m_netLICHn; CRSSIInterpolator* m_rssiMapper; unsigned char m_rssi; unsigned char m_maxRSSI; diff --git a/M17Defines.h b/M17Defines.h index 53b5f63..5129d9a 100644 --- a/M17Defines.h +++ b/M17Defines.h @@ -24,14 +24,16 @@ const unsigned int M17_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate const unsigned int M17_FRAME_LENGTH_BITS = 384U; const unsigned int M17_FRAME_LENGTH_BYTES = M17_FRAME_LENGTH_BITS / 8U; -const unsigned char M17_SYNC_BYTES[] = {0x32U, 0x43U}; +const unsigned char M17_HEADER_SYNC_BYTES[] = {0x5DU, 0xDDU}; +const unsigned char M17_DATA_SYNC_BYTES[] = {0xDDU, 0xDDU}; + 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_LICH_FRAGMENT_LENGTH_BITS = M17_LICH_LENGTH_BITS / 5U; +const unsigned int M17_LICH_FRAGMENT_LENGTH_BITS = M17_LICH_LENGTH_BITS / 6U; const unsigned int M17_LICH_FRAGMENT_LENGTH_BYTES = M17_LICH_FRAGMENT_LENGTH_BITS / 8U; const unsigned int M17_LICH_FRAGMENT_FEC_LENGTH_BITS = M17_LICH_FRAGMENT_LENGTH_BITS * 2U; diff --git a/M17LICH.cpp b/M17LICH.cpp index 0c0469a..e99fd8d 100644 --- a/M17LICH.cpp +++ b/M17LICH.cpp @@ -124,23 +124,19 @@ void CM17LICH::setLinkSetup(const unsigned char* data) m_valid = CM17CRC::checkCRC(m_lich, M17_LICH_LENGTH_BYTES); } -void CM17LICH::getFragment(unsigned char* data, unsigned short fn) const +void CM17LICH::getFragment(unsigned char* data, unsigned int n) const { assert(data != NULL); CM17CRC::encodeCRC(m_lich, M17_LICH_LENGTH_BYTES); - unsigned int n = (fn & 0x7FFFU) % 5U; - ::memcpy(data, m_lich + (n * M17_LICH_FRAGMENT_LENGTH_BYTES), M17_LICH_FRAGMENT_LENGTH_BYTES); } -void CM17LICH::setFragment(const unsigned char* data, unsigned short fn) +void CM17LICH::setFragment(const unsigned char* data, unsigned int n) { assert(data != NULL); - unsigned int n = (fn & 0x7FFFU) % 5U; - ::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/M17LICH.h b/M17LICH.h index 8842e22..804de3e 100644 --- a/M17LICH.h +++ b/M17LICH.h @@ -46,8 +46,8 @@ public: void getLinkSetup(unsigned char* data) const; void setLinkSetup(const unsigned char* data); - void getFragment(unsigned char* data, unsigned short fn) const; - void setFragment(const unsigned char* data, unsigned short fn); + void getFragment(unsigned char* data, unsigned int n) const; + void setFragment(const unsigned char* data, unsigned int n); private: unsigned char* m_lich; diff --git a/MMDVM.ini b/MMDVM.ini index f26c7e9..13a2369 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -133,6 +133,7 @@ TXHang=5 [M17] Enable=1 +ColorCode=3 SelfOnly=0 TXHang=5 # ModeHang=10 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index d62b126..ee52f5e 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -619,18 +619,20 @@ int CMMDVMHost::run() } if (m_m17Enabled) { - bool selfOnly = m_conf.getM17SelfOnly(); - bool allowEncryption = m_conf.getM17AllowEncryption(); - unsigned int txHang = m_conf.getM17TXHang(); - m_m17RFModeHang = m_conf.getM17ModeHang(); + bool selfOnly = m_conf.getM17SelfOnly(); + unsigned int colorCode = m_conf.getM17ColorCode(); + 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(" Allow Encryption: %s", allowEncryption ? "yes" : "no"); LogInfo(" TX Hang: %us", txHang); LogInfo(" Mode Hang: %us", m_m17RFModeHang); - m_m17 = new CM17Control(m_callsign, selfOnly, allowEncryption, m_m17Network, m_display, m_timeout, m_duplex, rssi); + m_m17 = new CM17Control(m_callsign, colorCode, selfOnly, allowEncryption, m_m17Network, m_display, m_timeout, m_duplex, rssi); } CTimer pocsagTimer(1000U, 30U); diff --git a/SerialModem.cpp b/SerialModem.cpp index 4305b2c..711daa0 100644 --- a/SerialModem.cpp +++ b/SerialModem.cpp @@ -79,8 +79,9 @@ const unsigned char MMDVM_P25_LOST = 0x32U; const unsigned char MMDVM_NXDN_DATA = 0x40U; const unsigned char MMDVM_NXDN_LOST = 0x41U; -const unsigned char MMDVM_M17_DATA = 0x45U; -const unsigned char MMDVM_M17_LOST = 0x46U; +const unsigned char MMDVM_M17_HEADER = 0x45U; +const unsigned char MMDVM_M17_DATA = 0x46U; +const unsigned char MMDVM_M17_LOST = 0x47U; const unsigned char MMDVM_POCSAG_DATA = 0x50U; @@ -661,6 +662,20 @@ void CSerialModem::clock(unsigned int ms) } break; + case MMDVM_M17_HEADER: { + if (m_trace) + CUtils::dump(1U, "RX M17 Header", m_buffer, m_length); + + unsigned char data = m_length - 2U; + m_rxM17Data.addData(&data, 1U); + + data = TAG_HEADER; + m_rxM17Data.addData(&data, 1U); + + m_rxM17Data.addData(m_buffer + 3U, m_length - 3U); + } + break; + case MMDVM_M17_DATA: { if (m_trace) CUtils::dump(1U, "RX M17 Data", m_buffer, m_length); @@ -1017,8 +1032,12 @@ void CSerialModem::clock(unsigned int ms) m_txM17Data.getData(&len, 1U); m_txM17Data.getData(m_buffer, len); - if (m_trace) - CUtils::dump(1U, "TX M17 Data", m_buffer, len); + if (m_trace) { + if (m_buffer[2U] == MMDVM_M17_HEADER) + CUtils::dump(1U, "TX M17 Header", m_buffer, len); + else + CUtils::dump(1U, "TX M17 Data", m_buffer, len); + } int ret = m_serial->write(m_buffer, len); if (ret != int(len)) @@ -1460,14 +1479,18 @@ bool CSerialModem::writeM17Data(const unsigned char* data, unsigned int length) assert(data != NULL); assert(length > 0U); - if (data[0U] != TAG_DATA && data[0U] != TAG_EOT) + 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; - buffer[2U] = MMDVM_M17_DATA; + + if (data[0U] == TAG_HEADER) + buffer[2U] = MMDVM_M17_HEADER; + else + buffer[2U] = MMDVM_M17_DATA; ::memcpy(buffer + 3U, data + 1U, length - 1U); diff --git a/Sync.cpp b/Sync.cpp index 34dec37..3e53f64 100644 --- a/Sync.cpp +++ b/Sync.cpp @@ -85,9 +85,16 @@ void CSync::addNXDNSync(unsigned char* data) data[i] = (data[i] & ~NXDN_FSW_BYTES_MASK[i]) | NXDN_FSW_BYTES[i]; } -void CSync::addM17Sync(unsigned char* data) +void CSync::addM17HeaderSync(unsigned char* data) { assert(data != NULL); - ::memcpy(data, M17_SYNC_BYTES, M17_SYNC_LENGTH_BYTES); + ::memcpy(data, M17_HEADER_SYNC_BYTES, M17_SYNC_LENGTH_BYTES); +} + +void CSync::addM17DataSync(unsigned char* data) +{ + assert(data != NULL); + + ::memcpy(data, M17_DATA_SYNC_BYTES, M17_SYNC_LENGTH_BYTES); } diff --git a/Sync.h b/Sync.h index 2118c96..20ee2dd 100644 --- a/Sync.h +++ b/Sync.h @@ -33,7 +33,8 @@ public: static void addNXDNSync(unsigned char* data); - static void addM17Sync(unsigned char* data); + static void addM17HeaderSync(unsigned char* data); + static void addM17DataSync(unsigned char* data); private: }; diff --git a/Version.h b/Version.h index f021258..c648bad 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20201124"; +const char* VERSION = "20201126"; #endif