Add the NXDN LICH processing.

This commit is contained in:
Jonathan Naylor 2018-01-16 20:10:35 +00:00
parent b3169cbd4e
commit e0a5ae7fb3
15 changed files with 374 additions and 46 deletions

View file

@ -784,8 +784,7 @@ int CMMDVMHost::run()
if (m_mode == MODE_NXDN) {
m_modem->writeNXDNData(data, len);
m_modeTimer.start();
}
else if (m_mode != MODE_LOCKOUT) {
} else if (m_mode != MODE_LOCKOUT) {
LogWarning("NXDN data received when in mode %u", m_mode);
}
}

View file

@ -195,6 +195,7 @@
<ClInclude Include="NullDisplay.h" />
<ClInclude Include="NXDNControl.h" />
<ClInclude Include="NXDNDefines.h" />
<ClInclude Include="NXDNLICH.h" />
<ClInclude Include="NXDNNetwork.h" />
<ClInclude Include="P25Audio.h" />
<ClInclude Include="P25Control.h" />
@ -269,6 +270,7 @@
<ClCompile Include="Nextion.cpp" />
<ClCompile Include="NullDisplay.cpp" />
<ClCompile Include="NXDNControl.cpp" />
<ClCompile Include="NXDNLICH.cpp" />
<ClCompile Include="NXDNNetwork.cpp" />
<ClCompile Include="P25Audio.cpp" />
<ClCompile Include="P25Control.cpp" />

View file

@ -239,6 +239,9 @@
<ClInclude Include="NXDNNetwork.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NXDNLICH.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="BPTC19696.cpp">
@ -445,5 +448,8 @@
<ClCompile Include="NXDNNetwork.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NXDNLICH.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -9,9 +9,10 @@ LDFLAGS = -g
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 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
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 NXDNLICH.o \
NXDNNetwork.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

View file

@ -9,9 +9,10 @@ LDFLAGS = -g -L/usr/local/lib
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 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
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 NXDNLICH.o \
NXDNNetwork.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

View file

@ -10,8 +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 \
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
NXDNLICH.o NXDNNetwork.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

View file

@ -10,8 +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 \
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
NXDNLICH.o NXDNNetwork.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

View file

@ -10,8 +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 \
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
NXDNLICH.o NXDNNetwork.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

View file

@ -10,8 +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 \
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
NXDNLICH.o NXDNNetwork.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

View file

@ -9,9 +9,10 @@ LDFLAGS = -g
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 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
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 \
NXDNLICH.o NXDNNetwork.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

View file

@ -51,6 +51,7 @@ m_rfErrs(0U),
m_rfBits(1U),
m_netErrs(0U),
m_netBits(1U),
m_lastLICH(),
m_netN(0U),
m_rssiMapper(rssiMapper),
m_rssi(0U),
@ -115,49 +116,74 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
m_rssiCount++;
}
CUtils::dump(2U, "NXDN, raw data", data, len);
scrambler(data + 2U);
CYSFFICH fich;
bool valid = fich.decode(data + 2U);
CUtils::dump(2U, "NXDN, after descrambling", data, len);
CNXDNLICH lich;
bool valid = lich.decode(data + 2U);
if (valid)
m_lastFICH = fich;
m_lastLICH = lich;
// Stop repeater packets coming through, unless we're acting as a remote gateway
if (m_remoteGateway) {
unsigned char mr = m_lastFICH.getMR();
if (mr != YSF_MR_BUSY)
unsigned char direction = m_lastLICH.getDirection();
if (direction != NXDN_LICH_DIRECTION_INBOUND)
return false;
} else {
unsigned char mr = m_lastFICH.getMR();
if (mr == YSF_MR_BUSY)
unsigned char direction = m_lastLICH.getDirection();
if (direction == NXDN_LICH_DIRECTION_OUTBOUND)
return false;
}
unsigned char dt = m_lastFICH.getDT();
unsigned char usc = m_lastLICH.getFCT();
unsigned char option = m_lastLICH.getOption();
bool ret = false;
switch (dt) {
case YSF_DT_VOICE_FR_MODE:
ret = processVWData(valid, data);
break;
#ifdef notdef
if (usc == NXDN_LICH_USC_SACCH_NS || usc == NXDN_LICH_USC_SACCH_SS) {
switch (option) {
case NXDN_LICH_STEAL_NONE:
ret = processVCHOnly(valid, data);
break;
case YSF_DT_VD_MODE1:
case YSF_DT_VD_MODE2:
ret = processDNData(valid, data);
break;
case NXDN_LICH_STEAL_FACCH1_1:
ret = processFACCH11(valid, data);
break;
case YSF_DT_DATA_FR_MODE:
ret = processFRData(valid, data);
break;
case NXDN_LICH_STEAL_FACCH1_2:
ret = processFACCH12(valid, data);
break;
default:
break;
case NXDN_LICH_STEAL_FACCH:
ret = processFACCH1(valid, data);
break;
default:
break;
}
} else if (usc == NXDN_LICH_USC_UDCH) {
switch (option) {
case NXDN_LICH_STEAL_NONE:
ret = processUDCH(valid, data);
break;
case NXDN_LICH_STEAL_FACCH:
ret = processFACCH2(valid, data);
break;
default:
break;
}
}
#endif
return ret;
}
#ifdef notdef
bool CNXDNControl::processVWData(bool valid, unsigned char *data)
{
unsigned char fi = m_lastFICH.getFI();
@ -810,6 +836,8 @@ bool CNXDNControl::processFRData(bool valid, unsigned char *data)
return false;
}
#endif
unsigned int CNXDNControl::readModem(unsigned char* data)
{
assert(data != NULL);
@ -857,6 +885,8 @@ void CNXDNControl::writeEndNet()
m_network->reset();
}
#ifdef notdef
void CNXDNControl::writeNetwork()
{
unsigned char data[200U];
@ -986,10 +1016,14 @@ void CNXDNControl::writeNetwork()
}
}
#endif
void CNXDNControl::clock(unsigned int ms)
{
#ifdef notdef
if (m_network != NULL)
writeNetwork();
#endif
m_rfTimeoutTimer.clock(ms);
m_netTimeoutTimer.clock(ms);

View file

@ -25,7 +25,7 @@
// #include "YSFPayload.h"
#include "RingBuffer.h"
#include "StopWatch.h"
// #include "YSFFICH.h"
#include "NXDNLICH.h"
#include "Display.h"
#include "Defines.h"
#include "Timer.h"
@ -67,6 +67,7 @@ private:
unsigned int m_rfBits;
unsigned int m_netErrs;
unsigned int m_netBits;
CNXDNLICH m_lastLICH;
unsigned char m_netN;
CRSSIInterpolator* m_rssiMapper;
unsigned char m_rssi;
@ -76,9 +77,12 @@ private:
unsigned int m_rssiCount;
FILE* m_fp;
bool processVWData(bool valid, unsigned char *data);
bool processDNData(bool valid, unsigned char *data);
bool processFRData(bool valid, unsigned char *data);
bool processVCHOnly(bool valid, unsigned char *data);
bool processFACCH11(bool valid, unsigned char *data);
bool processFACCH12(bool valid, unsigned char *data);
bool processFACCH1(bool valid, unsigned char *data);
bool processUDCH(bool valid, unsigned char *data);
bool processFACCH2(bool valid, unsigned char *data);
void writeQueueRF(const unsigned char* data);
void writeQueueNet(const unsigned char* data);

View file

@ -31,5 +31,24 @@ const unsigned char NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U};
const unsigned char NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U};
const unsigned int NXDN_FSW_BYTES_LENGTH = 3U;
#endif
const unsigned int NXDN_LICH_LENGTH_BITS = 16U;
const unsigned char NXDN_LICH_RFCT_RCCH = 0U;
const unsigned char NXDN_LICH_RFCT_RTCH = 1U;
const unsigned char NXDN_LICH_RFCT_RDCH = 2U;
const unsigned char NXDN_LICH_RFCT_RTCH_C = 3U;
const unsigned char NXDN_LICH_USC_SACCH_NS = 0U;
const unsigned char NXDN_LICH_USC_UDCH = 1U;
const unsigned char NXDN_LICH_USC_SACCH_SS = 2U;
const unsigned char NXDN_LICH_USC_SACCH_SS_IDLE = 3U;
const unsigned char NXDN_LICH_STEAL_NONE = 3U;
const unsigned char NXDN_LICH_STEAL_FACCH1_2 = 2U;
const unsigned char NXDN_LICH_STEAL_FACCH1_1 = 1U;
const unsigned char NXDN_LICH_STEAL_FACCH = 0U;
const unsigned char NXDN_LICH_DIRECTION_INBOUND = 0U;
const unsigned char NXDN_LICH_DIRECTION_OUTBOUND = 1U;
#endif

209
NXDNLICH.cpp Normal file
View file

@ -0,0 +1,209 @@
/*
* 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 "NXDNLICH.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
#include <cstring>
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])
CNXDNLICH::CNXDNLICH(const CNXDNLICH& lich) :
m_lich(lich.m_lich)
{
}
CNXDNLICH::CNXDNLICH() :
m_lich(0U)
{
}
CNXDNLICH::~CNXDNLICH()
{
}
bool CNXDNLICH::decode(const unsigned char* bytes)
{
assert(bytes != NULL);
unsigned char lich[1U];
lich[0U] = 0x00U;
unsigned int offset = NXDN_FSW_LENGTH_BITS;
bool b7 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 7U, b7);
offset++;
bool b6 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 6U, b6);
offset++;
bool b5 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 5U, b5);
offset++;
bool b4 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 4U, b4);
offset++;
bool b3 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 3U, b3);
offset++;
bool b2 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 2U, b2);
offset++;
bool b1 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 1U, b1);
offset++;
bool b0 = READ_BIT1(bytes, offset);
WRITE_BIT1(lich, 0U, b0);
bool parity = b7 ^ b6 ^ b5 ^ b4;
LogMessage("NXDN, LICH bits: %d%d %d%d %d%d %d - %d, parity: %d", b7 ? 1 : 0, b6 ? 1 : 0, b5 ? 1 : 0, b4 ? 1 : 0, b3 ? 1 : 0, b2 ? 1 : 0, b1 ? 1 : 0, b0 ? 1 : 0, parity ? 1 : 0);
if (parity != b0)
return false;
m_lich = lich[0U] >> 1;
return true;
}
void CNXDNLICH::encode(unsigned char* bytes)
{
assert(bytes != NULL);
unsigned char lich[1U];
lich[0U] = m_lich << 1;
bool b7 = READ_BIT1(lich, 7U);
bool b6 = READ_BIT1(lich, 6U);
bool b5 = READ_BIT1(lich, 5U);
bool b4 = READ_BIT1(lich, 4U);
bool b3 = READ_BIT1(lich, 3U);
bool b2 = READ_BIT1(lich, 2U);
bool b1 = READ_BIT1(lich, 1U);
bool b0 = READ_BIT1(lich, 0U);
bool parity = b7 ^ b6 ^ b5 ^ b4;
WRITE_BIT1(lich, 0U, parity);
unsigned int offset = NXDN_FSW_LENGTH_BITS;
WRITE_BIT1(bytes, offset, b7);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b6);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b5);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b4);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b3);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b2);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b1);
offset++;
WRITE_BIT1(bytes, offset, true);
offset++;
WRITE_BIT1(bytes, offset, b0);
offset++;
WRITE_BIT1(bytes, offset, true);
}
unsigned char CNXDNLICH::getRFCT() const
{
return (m_lich >> 5) & 0x03U;
}
unsigned char CNXDNLICH::getFCT() const
{
return (m_lich >> 3) & 0x03U;
}
unsigned char CNXDNLICH::getOption() const
{
return (m_lich >> 1) & 0x03U;
}
unsigned char CNXDNLICH::getDirection() const
{
return m_lich & 0x01U;
}
void CNXDNLICH::setRFCT(unsigned char rfct)
{
m_lich &= 0x1FU;
m_lich |= (rfct << 5) & 0x60U;
}
void CNXDNLICH::setFCT(unsigned char usc)
{
m_lich &= 0x67U;
m_lich |= (usc << 3) & 0x18U;
}
void CNXDNLICH::setOption(unsigned char option)
{
m_lich &= 0x79U;
m_lich |= (option << 1) & 0x06U;
}
void CNXDNLICH::setDirection(unsigned char direction)
{
m_lich &= 0x7EU;
m_lich |= direction & 0x01U;
}
CNXDNLICH& CNXDNLICH::operator=(const CNXDNLICH& lich)
{
if (&lich != this)
m_lich = lich.m_lich;
return *this;
}

48
NXDNLICH.h Normal file
View file

@ -0,0 +1,48 @@
/*
* 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(NXDNLICH_H)
#define NXDNLICH_H
class CNXDNLICH {
public:
CNXDNLICH(const CNXDNLICH& fich);
CNXDNLICH();
~CNXDNLICH();
bool decode(const unsigned char* bytes);
void encode(unsigned char* bytes);
unsigned char getRFCT() const;
unsigned char getFCT() const;
unsigned char getOption() const;
unsigned char getDirection() const;
void setRFCT(unsigned char rfct);
void setFCT(unsigned char usc);
void setOption(unsigned char option);
void setDirection(unsigned char direction);
CNXDNLICH& operator=(const CNXDNLICH& fich);
private:
unsigned char m_lich;
};
#endif