From c549cf3594d2e1b5676b1229f7c874f2d3baf3b2 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 18 Oct 2020 20:44:03 +0100 Subject: [PATCH] Add the LICH processing. --- M17Control.cpp | 15 ++-- M17LICH.cpp | 160 ++++++++++++++++++++++++++++++++++++++ M17LICH.h | 9 ++- M17Network.cpp | 7 +- M17Network.h | 1 - MMDVMHost.vcxproj | 1 + MMDVMHost.vcxproj.filters | 3 + 7 files changed, 182 insertions(+), 14 deletions(-) create mode 100644 M17LICH.cpp diff --git a/M17Control.cpp b/M17Control.cpp index 3086c1b..754ccc0 100644 --- a/M17Control.cpp +++ b/M17Control.cpp @@ -45,9 +45,9 @@ const unsigned int INTERLEAVER[] = { 8U, 145U, 98U, 235U, 188U, 325U, 278U, 47U}; const unsigned char SCRAMBLER[] = { - 0xD6U, 0xB5U, 0xE2U, 0x30U, 0x82U, 0xFFU, 0x84U, 0x62U, 0xBAU, 0x4EU, 0x96U, 0x90U, 0xD8U, 0x98U, 0xDDU, 0x5DU, 0x0CU, - 0xC8U, 0x52U, 0x43U, 0x91U, 0x1DU, 0xF8U, 0x6EU, 0x68U, 0x2FU, 0x35U, 0xDAU, 0x14U, 0xEAU, 0xCDU, 0x76U, 0x19U, 0x8DU, - 0xD5U, 0x80U, 0xD1U, 0x33U, 0x87U, 0x13U, 0x57U, 0x18U, 0x2DU, 0x29U, 0x78U, 0xC3U}; + 0x00U, 0x00U, 0xD6U, 0xB5U, 0xE2U, 0x30U, 0x82U, 0xFFU, 0x84U, 0x62U, 0xBAU, 0x4EU, 0x96U, 0x90U, 0xD8U, 0x98U, 0xDDU, + 0x5DU, 0x0CU, 0xC8U, 0x52U, 0x43U, 0x91U, 0x1DU, 0xF8U, 0x6EU, 0x68U, 0x2FU, 0x35U, 0xDAU, 0x14U, 0xEAU, 0xCDU, 0x76U, + 0x19U, 0x8DU, 0xD5U, 0x80U, 0xD1U, 0x33U, 0x87U, 0x13U, 0x57U, 0x18U, 0x2DU, 0x29U, 0x78U, 0xC3U}; // #define DUMP_M17 @@ -417,7 +417,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len) unsigned char netData[M17_LICH_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES]; - m_rfLICH.getNetworkData(netData + 0U); + m_rfLICH.getNetwork(netData + 0U); // Copy the FN and payload from the frame ::memcpy(netData + M17_LICH_LENGTH_BYTES, frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES); @@ -507,7 +507,7 @@ void CM17Control::writeNetwork() m_networkWatchdog.start(); if (m_netState == RS_NET_IDLE) { - m_netLICH.setNetworkData(netData); + m_netLICH.setNetwork(netData); std::string source = m_netLICH.getSource(); std::string dest = m_netLICH.getDest(); @@ -725,8 +725,9 @@ void CM17Control::decorrelator(const unsigned char* in, unsigned char* out) cons assert(in != NULL); assert(out != NULL); - for (unsigned int i = M17_SYNC_LENGTH_BYTES; i < M17_FRAME_LENGTH_BYTES; i++) - out[i] = in[i] ^ SCRAMBLER[i - M17_SYNC_LENGTH_BYTES]; + for (unsigned int i = M17_SYNC_LENGTH_BYTES; i < M17_FRAME_LENGTH_BYTES; i++) { + out[i] = in[i] ^ SCRAMBLER[i]; + } } bool CM17Control::openFile() diff --git a/M17LICH.cpp b/M17LICH.cpp new file mode 100644 index 0000000..228f096 --- /dev/null +++ b/M17LICH.cpp @@ -0,0 +1,160 @@ +/* + * 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 "M17CRC.h" + +#include + +CM17LICH::CM17LICH(const CM17LICH& lich) : +m_lich(NULL), +m_valid(false) +{ + m_lich = new unsigned char[30U]; + + ::memcpy(m_lich, lich.m_lich, 30U); + + m_valid = lich.m_valid; +} + +CM17LICH::CM17LICH() : +m_lich(NULL), +m_valid(false) +{ + m_lich = new unsigned char[30U]; +} + +CM17LICH::~CM17LICH() +{ + delete[] m_lich; +} + +void CM17LICH::getNetwork(unsigned char* data) const +{ + assert(data != NULL); + + ::memcpy(data, m_lich, 28U); +} + +void CM17LICH::setNetwork(const unsigned char* data) +{ + assert(data != NULL); + + ::memcpy(m_lich, data, 28U); + + m_valid = true; +} + +std::string CM17LICH::getSource() const +{ + if (!m_valid) + return ""; + + 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 +{ + if (!m_valid) + return ""; + + 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 +{ + if (!m_valid) + return 0U; + + return (m_lich[12U] >> 1) & 0x03U; +} + +void CM17LICH::setDataType(unsigned char type) +{ + m_lich[12U] &= 0xF9U; + m_lich[12U] |= (type << 1) & 0x06U; +} + +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, 30U); + + CM17CRC::encodeCRC(data, 30U); +} + +void CM17LICH::setLinkSetup(const unsigned char* data) +{ + assert(data != NULL); + + ::memcpy(m_lich, data, 30U); + + m_valid = CM17CRC::checkCRC(m_lich, 30U); +} + +void CM17LICH::getFragment(unsigned char* data, unsigned short fn) const +{ + assert(data != NULL); + + CM17CRC::encodeCRC(m_lich, 30U); + + unsigned int n = (fn & 0x7FFFU) % 5U; + + ::memcpy(data, m_lich + (n * 6U), 6U); +} + +void CM17LICH::setFragment(const unsigned char* data, unsigned short fn) +{ + assert(data != NULL); + + unsigned int n = (fn & 0x7FFFU) % 5U; + + ::memcpy(m_lich + (n * 6U), data, 6U); + + m_valid = CM17CRC::checkCRC(m_lich, 30U); +} diff --git a/M17LICH.h b/M17LICH.h index 4ab48d0..b4855f6 100644 --- a/M17LICH.h +++ b/M17LICH.h @@ -27,8 +27,8 @@ public: CM17LICH(); ~CM17LICH(); - void getNetworkData(unsigned char* data); - void setNetworkData(const unsigned char* data); + void getNetwork(unsigned char* data) const; + void setNetwork(const unsigned char* data); std::string getSource() const; void setSource(const std::string& callsign); @@ -43,15 +43,16 @@ public: bool isValid() const; void getLinkSetup(unsigned char* data) const; - void setLinkSetup(const unsigned char* data) const; + void setLinkSetup(const unsigned char* data); - void getFragment(unsigned char* data, unsigned short fn); + void getFragment(unsigned char* data, unsigned short fn) const; void setFragment(const unsigned char* data, unsigned short fn); CM17LICH& operator=(const CM17LICH& lich); private: unsigned char* m_lich; + bool m_valid; }; #endif diff --git a/M17Network.cpp b/M17Network.cpp index 7a3c6ff..d6b273e 100644 --- a/M17Network.cpp +++ b/M17Network.cpp @@ -31,7 +31,6 @@ const unsigned int BUFFER_LENGTH = 200U; CM17Network::CM17Network(const std::string& callsign, unsigned int port, bool debug) : -m_callsign(callsign), m_socket(port), m_addr(), m_addrLen(0U), @@ -52,7 +51,11 @@ m_timer(1000U, 5U) m_encoded = new unsigned char[6U]; - CM17Utils::encodeCallsign(m_callsign, m_encoded); + std::string call = callsign; + call.resize(8U, ' '); + call += "D"; + + CM17Utils::encodeCallsign(call, m_encoded); } CM17Network::~CM17Network() diff --git a/M17Network.h b/M17Network.h index ff357cf..ed6e81c 100644 --- a/M17Network.h +++ b/M17Network.h @@ -58,7 +58,6 @@ public: void clock(unsigned int ms); private: - std::string m_callsign; CUDPSocket m_socket; sockaddr_storage m_addr; unsigned int m_addrLen; diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index e1a78c7..15665a0 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -292,6 +292,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index c1bd903..d024110 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -595,5 +595,8 @@ Source Files + + Source Files + \ No newline at end of file