From ba31b6d8a717a55a91d8a505336e130d5f72e09b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 30 Jan 2018 19:51:47 +0000 Subject: [PATCH] Add decoding of the Layer 3 messages. --- MMDVMHost.vcxproj | 2 + MMDVMHost.vcxproj.filters | 6 +++ Makefile | 6 +-- Makefile.Pi | 6 +-- Makefile.Pi.Adafruit | 6 +-- Makefile.Pi.HD44780 | 2 +- Makefile.Pi.OLED | 6 +-- Makefile.Pi.PCF8574 | 2 +- Makefile.Solaris | 6 +-- NXDNControl.cpp | 87 ++++++++++++++++++++++++++++++++--- NXDNControl.h | 5 +- NXDNDefines.h | 22 +++++++++ NXDNLayer3.cpp | 97 +++++++++++++++++++++++++++++++++++++++ NXDNLayer3.h | 43 +++++++++++++++++ 14 files changed, 272 insertions(+), 24 deletions(-) create mode 100644 NXDNLayer3.cpp create mode 100644 NXDNLayer3.h diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 21583f8..ef4390c 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -199,6 +199,7 @@ + @@ -281,6 +282,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index c0b4ae1..8bd9368 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -263,6 +263,9 @@ Header Files + + Header Files + @@ -493,5 +496,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index 9176107..57470a5 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,9 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \ + SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi b/Makefile.Pi index 900cfc0..97e713e 100644 --- a/Makefile.Pi +++ b/Makefile.Pi @@ -10,9 +10,9 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \ + SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index a46caee..7de9641 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -10,9 +10,9 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o \ - Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ + StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 5bde70a..9b1d770 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -10,7 +10,7 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o \ + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index c2974e8..008bc77 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -10,9 +10,9 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o JitterBuffer.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \ + SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index d4dacca..f16f7ff 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -10,7 +10,7 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o \ + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o diff --git a/Makefile.Solaris b/Makefile.Solaris index 3a93712..1fede3a 100644 --- a/Makefile.Solaris +++ b/Makefile.Solaris @@ -10,9 +10,9 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NXDNControl.o \ - NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNFACCH2.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 QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \ + SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 4aef87c..ddb1f0f 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -63,7 +63,9 @@ m_rfErrs(0U), m_rfBits(1U), m_netErrs(0U), m_netBits(1U), -m_lastLICH(), +m_rfLastLICH(), +m_rfSACCHMessage(), +m_rfMask(0x00U), m_netN(0U), m_rssiMapper(rssiMapper), m_rssi(0U), @@ -139,21 +141,21 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) bool valid = lich.decode(data + 2U); if (valid) - m_lastLICH = lich; + m_rfLastLICH = lich; // Stop repeater packets coming through, unless we're acting as a remote gateway if (m_remoteGateway) { - unsigned char direction = m_lastLICH.getDirection(); + unsigned char direction = m_rfLastLICH.getDirection(); if (direction == NXDN_LICH_DIRECTION_INBOUND) return false; } else { - unsigned char direction = m_lastLICH.getDirection(); + unsigned char direction = m_rfLastLICH.getDirection(); if (direction == NXDN_LICH_DIRECTION_OUTBOUND) return false; } - unsigned char usc = m_lastLICH.getFCT(); - unsigned char option = m_lastLICH.getOption(); + unsigned char usc = m_rfLastLICH.getFCT(); + unsigned char option = m_rfLastLICH.getOption(); bool ret; if (usc == NXDN_LICH_USC_UDCH) @@ -174,6 +176,77 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne return false; } + if (m_rfState == RS_RF_LISTENING && !valid) + return false; + + if (m_rfState == RS_RF_LISTENING) { + unsigned char message[3U]; + sacch.getData(message); + + unsigned char structure = sacch.getStructure(); + switch (structure) { + case NXDN_SR_1_4: + m_rfMask |= 0x01U; + m_rfSACCHMessage.decode(message, 18U, 0U); + break; + case NXDN_SR_2_4: + m_rfMask |= 0x02U; + m_rfSACCHMessage.decode(message, 18U, 18U); + break; + case NXDN_SR_3_4: + m_rfMask |= 0x04U; + m_rfSACCHMessage.decode(message, 18U, 36U); + break; + case NXDN_SR_4_4: + m_rfMask |= 0x08U; + m_rfSACCHMessage.decode(message, 18U, 54U); + break; + default: + break; + } + + if (m_rfMask != 0x0FU) + return false; + + unsigned char messageType = m_rfSACCHMessage.getMessageType(); + if (messageType == NXDN_MESSAGE_TYPE_IDLE) + return false; + + unsigned short srcId = m_rfSACCHMessage.getSourceUnitId(); + unsigned short dstId = m_rfSACCHMessage.getDestinationGroupId(); + bool grp = m_rfSACCHMessage.getIsGroup(); + + if (m_selfOnly) { + if (srcId != m_id) { + m_rfState = RS_RF_REJECTED; + return false; + } + } + + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_rfState = RS_RF_AUDIO; + + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_NXDN) + openFile(); +#endif + std::string source = m_lookup->find(srcId); + LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); + m_display->writeNXDN(source.c_str(), grp, dstId, "R"); + + m_rfState = RS_RF_AUDIO; + } + + // XXX What about rejected? + if (m_rfState != RS_RF_AUDIO) + return false; + if (option == NXDN_LICH_STEAL_NONE) { CAMBEFEC ambe; unsigned int errors = 0U; @@ -749,6 +822,8 @@ void CNXDNControl::writeEndRF() { m_rfState = RS_RF_LISTENING; + m_rfMask = 0x00U; + m_rfTimeoutTimer.stop(); if (m_netState == RS_NET_IDLE) { diff --git a/NXDNControl.h b/NXDNControl.h index da2fd12..f181b81 100644 --- a/NXDNControl.h +++ b/NXDNControl.h @@ -22,6 +22,7 @@ #include "RSSIInterpolator.h" #include "NXDNNetwork.h" #include "NXDNDefines.h" +#include "NXDNLayer3.h" #include "NXDNLookup.h" #include "RingBuffer.h" #include "StopWatch.h" @@ -68,7 +69,9 @@ private: unsigned int m_rfBits; unsigned int m_netErrs; unsigned int m_netBits; - CNXDNLICH m_lastLICH; + CNXDNLICH m_rfLastLICH; + CNXDNLayer3 m_rfSACCHMessage; + unsigned char m_rfMask; unsigned char m_netN; CRSSIInterpolator* m_rssiMapper; unsigned char m_rssi; diff --git a/NXDNDefines.h b/NXDNDefines.h index c9ab105..2cefccc 100644 --- a/NXDNDefines.h +++ b/NXDNDefines.h @@ -66,4 +66,26 @@ const unsigned char NXDN_SR_3_4 = 1U; const unsigned char NXDN_SR_2_4 = 2U; const unsigned char NXDN_SR_1_4 = 3U; +const unsigned char NXDN_MESSAGE_TYPE_VCALL = 0x01U; +const unsigned char NXDN_MESSAGE_TYPE_VCALL_IV = 0x03U; +const unsigned char NXDN_MESSAGE_TYPE_DCALL_HDR = 0x09U; +const unsigned char NXDN_MESSAGE_TYPE_DCALL_DATA = 0x0BU; +const unsigned char NXDN_MESSAGE_TYPE_DCALL_ACK = 0x0CU; +const unsigned char NXDN_MESSAGE_TYPE_TX_REL = 0x08U; +const unsigned char NXDN_MESSAGE_TYPE_HEAD_DLY = 0x0FU; +const unsigned char NXDN_MESSAGE_TYPE_SDCALL_REQ_HDR = 0x38U; +const unsigned char NXDN_MESSAGE_TYPE_SDCALL_REQ_DATA = 0x39U; +const unsigned char NXDN_MESSAGE_TYPE_SDCALL_RESP = 0x3BU; +const unsigned char NXDN_MESSAGE_TYPE_SDCALL_IV = 0x3AU; +const unsigned char NXDN_MESSAGE_TYPE_STAT_INQ_REQ = 0x30U; +const unsigned char NXDN_MESSAGE_TYPE_STAT_INQ_RESP = 0x31U; +const unsigned char NXDN_MESSAGE_TYPE_STAT_REQ = 0x32U; +const unsigned char NXDN_MESSAGE_TYPE_STAT_RESP = 0x33U; +const unsigned char NXDN_MESSAGE_TYPE_REM_CON_REQ = 0x34U; +const unsigned char NXDN_MESSAGE_TYPE_REM_CON_RESP = 0x35U; +const unsigned char NXDN_MESSAGE_TYPE_IDLE = 0x10U; +const unsigned char NXDN_MESSAGE_TYPE_AUTH_INQ_REQ = 0x28U; +const unsigned char NXDN_MESSAGE_TYPE_AUTH_INQ_RESP = 0x29U; +const unsigned char NXDN_MESSAGE_TYPE_PROP_FORM = 0x3FU; + #endif diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp new file mode 100644 index 0000000..bde954c --- /dev/null +++ b/NXDNLayer3.cpp @@ -0,0 +1,97 @@ +/* +* Copyright (C) 2018 by Jonathan Naylor G4KLX +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* 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 "NXDNDefines.h" +#include "NXDNLayer3.h" +#include "Log.h" + +#include +#include +#include + +const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U }; + +#define WRITE_BIT1(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_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) + +CNXDNLayer3::CNXDNLayer3(const CNXDNLayer3& layer3) : +m_data(NULL) +{ + m_data = new unsigned char[22U]; + ::memcpy(m_data, layer3.m_data, 22U); +} + +CNXDNLayer3::CNXDNLayer3() : +m_data(NULL) +{ + m_data = new unsigned char[22U]; + ::memset(m_data, 0x00U, 22U); +} + +CNXDNLayer3::~CNXDNLayer3() +{ + delete[] m_data; +} + +void CNXDNLayer3::decode(const unsigned char* bytes, unsigned int length, unsigned int offset) +{ + assert(bytes != NULL); + + for (unsigned int i = 0U; i < length; i++, offset++) { + bool b = READ_BIT1(bytes, offset); + WRITE_BIT1(m_data, i, b); + } +} + +void CNXDNLayer3::encode(unsigned char* bytes, unsigned int length, unsigned int offset) +{ + assert(bytes != NULL); + + for (unsigned int i = 0U; i < length; i++, offset++) { + bool b = READ_BIT1(m_data, i); + WRITE_BIT1(bytes, offset, b); + } +} + +unsigned char CNXDNLayer3::getMessageType() const +{ + return m_data[0U] & 0x3FU; +} + +unsigned short CNXDNLayer3::getSourceUnitId() const +{ + return (m_data[3U] << 8) | m_data[4U]; +} + +unsigned short CNXDNLayer3::getDestinationGroupId() const +{ + return (m_data[5U] << 8) | m_data[6U]; +} + +bool CNXDNLayer3::getIsGroup() const +{ + return (m_data[2U] & 0x80U) != 0x80U; +} + +CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3) +{ + if (&layer3 != this) + ::memcpy(m_data, layer3.m_data, 22U); + + return *this; +} diff --git a/NXDNLayer3.h b/NXDNLayer3.h new file mode 100644 index 0000000..f91d34d --- /dev/null +++ b/NXDNLayer3.h @@ -0,0 +1,43 @@ +/* +* Copyright (C) 2018 by Jonathan Naylor G4KLX +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* 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. +*/ + +#if !defined(NXDNLayer3_H) +#define NXDNLayer3_H + +class CNXDNLayer3 { +public: + CNXDNLayer3(const CNXDNLayer3& layer3); + CNXDNLayer3(); + ~CNXDNLayer3(); + + void decode(const unsigned char* bytes, unsigned int length, unsigned int offset = 0U); + + void encode(unsigned char* bytes, unsigned int length, unsigned int offset = 0U); + + unsigned char getMessageType() const; + unsigned short getSourceUnitId() const; + unsigned short getDestinationGroupId() const; + bool getIsGroup() const; + + CNXDNLayer3& operator=(const CNXDNLayer3& layer3); + +private: + unsigned char* m_data; +}; + +#endif