Merge remote-tracking branch 'g4klx/nxdn' into nxdn
This commit is contained in:
commit
0f9f24310a
25 changed files with 716 additions and 475 deletions
7
Conf.cpp
7
Conf.cpp
|
@ -299,6 +299,13 @@ bool CConf::read()
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Remove quotes from the value
|
||||||
|
size_t len = ::strlen(value);
|
||||||
|
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
|
||||||
|
value[len - 1U] = '\0';
|
||||||
|
value++;
|
||||||
|
}
|
||||||
|
|
||||||
if (section == SECTION_GENERAL) {
|
if (section == SECTION_GENERAL) {
|
||||||
if (::strcmp(key, "Callsign") == 0) {
|
if (::strcmp(key, "Callsign") == 0) {
|
||||||
// Convert the callsign to upper case
|
// Convert the callsign to upper case
|
||||||
|
|
|
@ -498,6 +498,9 @@ void CDMRNetwork::receiveData(const unsigned char* data, unsigned int length)
|
||||||
if (slotNo == 2U && !m_slot2)
|
if (slotNo == 2U && !m_slot2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_jitterBuffers[slotNo]->appendData(data, length);
|
||||||
|
|
||||||
|
/*
|
||||||
unsigned char dataType = data[15U] & 0x3FU;
|
unsigned char dataType = data[15U] & 0x3FU;
|
||||||
if (dataType == (0x20U | DT_CSBK) ||
|
if (dataType == (0x20U | DT_CSBK) ||
|
||||||
dataType == (0x20U | DT_DATA_HEADER) ||
|
dataType == (0x20U | DT_DATA_HEADER) ||
|
||||||
|
@ -511,6 +514,7 @@ void CDMRNetwork::receiveData(const unsigned char* data, unsigned int length)
|
||||||
unsigned char seqNo = data[4U];
|
unsigned char seqNo = data[4U];
|
||||||
m_jitterBuffers[slotNo]->addData(data, length, seqNo);
|
m_jitterBuffers[slotNo]->addData(data, length, seqNo);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDMRNetwork::writeLogin()
|
bool CDMRNetwork::writeLogin()
|
||||||
|
|
|
@ -198,7 +198,7 @@
|
||||||
<ClInclude Include="NXDNCRC.h" />
|
<ClInclude Include="NXDNCRC.h" />
|
||||||
<ClInclude Include="NXDNDefines.h" />
|
<ClInclude Include="NXDNDefines.h" />
|
||||||
<ClInclude Include="NXDNFACCH1.h" />
|
<ClInclude Include="NXDNFACCH1.h" />
|
||||||
<ClInclude Include="NXDNFACCH2.h" />
|
<ClInclude Include="NXDNLayer3.h" />
|
||||||
<ClInclude Include="NXDNLICH.h" />
|
<ClInclude Include="NXDNLICH.h" />
|
||||||
<ClInclude Include="NXDNLookup.h" />
|
<ClInclude Include="NXDNLookup.h" />
|
||||||
<ClInclude Include="NXDNNetwork.h" />
|
<ClInclude Include="NXDNNetwork.h" />
|
||||||
|
@ -280,7 +280,7 @@
|
||||||
<ClCompile Include="NXDNConvolution.cpp" />
|
<ClCompile Include="NXDNConvolution.cpp" />
|
||||||
<ClCompile Include="NXDNCRC.cpp" />
|
<ClCompile Include="NXDNCRC.cpp" />
|
||||||
<ClCompile Include="NXDNFACCH1.cpp" />
|
<ClCompile Include="NXDNFACCH1.cpp" />
|
||||||
<ClCompile Include="NXDNFACCH2.cpp" />
|
<ClCompile Include="NXDNLayer3.cpp" />
|
||||||
<ClCompile Include="NXDNLICH.cpp" />
|
<ClCompile Include="NXDNLICH.cpp" />
|
||||||
<ClCompile Include="NXDNLookup.cpp" />
|
<ClCompile Include="NXDNLookup.cpp" />
|
||||||
<ClCompile Include="NXDNNetwork.cpp" />
|
<ClCompile Include="NXDNNetwork.cpp" />
|
||||||
|
|
|
@ -257,10 +257,10 @@
|
||||||
<ClInclude Include="NXDNFACCH1.h">
|
<ClInclude Include="NXDNFACCH1.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="NXDNFACCH2.h">
|
<ClInclude Include="NXDNUDCH.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="NXDNUDCH.h">
|
<ClInclude Include="NXDNLayer3.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -487,10 +487,10 @@
|
||||||
<ClCompile Include="NXDNFACCH1.cpp">
|
<ClCompile Include="NXDNFACCH1.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="NXDNFACCH2.cpp">
|
<ClCompile Include="NXDNUDCH.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="NXDNUDCH.cpp">
|
<ClCompile Include="NXDNLayer3.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
6
Makefile
6
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 \
|
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 \
|
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 \
|
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 \
|
NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.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 \
|
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.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
|
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
|
all: MMDVMHost
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
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 \
|
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 \
|
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 \
|
NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.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 \
|
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.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
|
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
|
all: MMDVMHost
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
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 \
|
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 \
|
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 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 \
|
P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.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
|
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
|
all: MMDVMHost
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
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 \
|
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 \
|
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 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 \
|
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
|
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
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DOLED -I/usr/local/include
|
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DOLED -I/usr/local/include
|
||||||
LIBS = -lArduiPi_OLED -lpthread
|
LIBS = -lArduiPi_OLED -li2c -lpthread
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
LDFLAGS = -g -L/usr/local/lib
|
||||||
|
|
||||||
OBJECTS = \
|
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 \
|
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 \
|
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 \
|
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 \
|
NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.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 \
|
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.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
|
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
|
all: MMDVMHost
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
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 \
|
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 \
|
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 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 \
|
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
|
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
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
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 \
|
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 \
|
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 \
|
NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.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 \
|
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.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
|
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
|
all: MMDVMHost
|
||||||
|
|
||||||
|
|
601
NXDNControl.cpp
601
NXDNControl.cpp
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#include "NXDNControl.h"
|
#include "NXDNControl.h"
|
||||||
#include "NXDNFACCH1.h"
|
#include "NXDNFACCH1.h"
|
||||||
#include "NXDNFACCH2.h"
|
|
||||||
#include "NXDNSACCH.h"
|
#include "NXDNSACCH.h"
|
||||||
#include "NXDNUDCH.h"
|
#include "NXDNUDCH.h"
|
||||||
#include "AMBEFEC.h"
|
#include "AMBEFEC.h"
|
||||||
|
@ -63,7 +62,9 @@ m_rfErrs(0U),
|
||||||
m_rfBits(1U),
|
m_rfBits(1U),
|
||||||
m_netErrs(0U),
|
m_netErrs(0U),
|
||||||
m_netBits(1U),
|
m_netBits(1U),
|
||||||
m_lastLICH(),
|
m_rfLastLICH(),
|
||||||
|
m_rfLayer3(),
|
||||||
|
m_rfMask(0x00U),
|
||||||
m_netN(0U),
|
m_netN(0U),
|
||||||
m_rssiMapper(rssiMapper),
|
m_rssiMapper(rssiMapper),
|
||||||
m_rssi(0U),
|
m_rssi(0U),
|
||||||
|
@ -97,13 +98,14 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_REJECTED) {
|
if (type == TAG_LOST && m_rfState == RS_RF_DATA) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST) {
|
if (type == TAG_LOST) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RS_RF_LISTENING;
|
||||||
|
m_rfMask = 0x00U;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,21 +141,21 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
bool valid = lich.decode(data + 2U);
|
bool valid = lich.decode(data + 2U);
|
||||||
|
|
||||||
if (valid)
|
if (valid)
|
||||||
m_lastLICH = lich;
|
m_rfLastLICH = lich;
|
||||||
|
|
||||||
// Stop repeater packets coming through, unless we're acting as a remote gateway
|
// Stop repeater packets coming through, unless we're acting as a remote gateway
|
||||||
if (m_remoteGateway) {
|
if (m_remoteGateway) {
|
||||||
unsigned char direction = m_lastLICH.getDirection();
|
unsigned char direction = m_rfLastLICH.getDirection();
|
||||||
if (direction == NXDN_LICH_DIRECTION_INBOUND)
|
if (direction == NXDN_LICH_DIRECTION_INBOUND)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
unsigned char direction = m_lastLICH.getDirection();
|
unsigned char direction = m_rfLastLICH.getDirection();
|
||||||
if (direction == NXDN_LICH_DIRECTION_OUTBOUND)
|
if (direction == NXDN_LICH_DIRECTION_OUTBOUND)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char usc = m_lastLICH.getFCT();
|
unsigned char usc = m_rfLastLICH.getFCT();
|
||||||
unsigned char option = m_lastLICH.getOption();
|
unsigned char option = m_rfLastLICH.getOption();
|
||||||
|
|
||||||
bool ret;
|
bool ret;
|
||||||
if (usc == NXDN_LICH_USC_UDCH)
|
if (usc == NXDN_LICH_USC_UDCH)
|
||||||
|
@ -174,43 +176,159 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option == NXDN_LICH_STEAL_NONE) {
|
// XXX Reconstruct invalid LICH
|
||||||
CAMBEFEC ambe;
|
|
||||||
unsigned int errors = 0U;
|
|
||||||
//errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES);
|
|
||||||
//errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 9U);
|
|
||||||
//errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 18U);
|
|
||||||
//errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 27U);
|
|
||||||
//LogDebug("NXDN, EHR, AMBE FEC %u/188 (%.1f%%)", errors, float(errors) / 1.88F);
|
|
||||||
//errors += ambe.regenerateIMBE(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES);
|
|
||||||
//errors += ambe.regenerateIMBE(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 18U);
|
|
||||||
//LogDebug("NXDN, EFR, AMBE FEC %u/288 (%.1f%%)", errors, float(errors) / 2.88F);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef notdef
|
if (usc == NXDN_LICH_USC_SACCH_NS) {
|
||||||
unsigned char fi = m_lastFICH.getFI();
|
// The SACCH on a non-superblock frame is usually an idle and not interesting apart from the RAN.
|
||||||
if (valid && fi == YSF_FI_HEADER) {
|
CNXDNFACCH1 facch11;
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
bool valid1 = facch11.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
bool valid = m_rfPayload.processHeaderData(data + 2U);
|
|
||||||
if (!valid)
|
CNXDNFACCH1 facch12;
|
||||||
|
bool valid2 = facch12.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
|
||||||
|
unsigned char buffer[10U];
|
||||||
|
if (valid1)
|
||||||
|
facch11.getData(buffer);
|
||||||
|
else if (valid2)
|
||||||
|
facch12.getData(buffer);
|
||||||
|
|
||||||
|
if (valid1 || valid2) {
|
||||||
|
CNXDNLayer3 layer3;
|
||||||
|
layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
|
||||||
|
unsigned char type = layer3.getMessageType();
|
||||||
|
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||||
|
if (m_rfState != RS_RF_AUDIO) {
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
|
m_rfMask = 0x00U;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
m_rfSource = m_rfPayload.getSource();
|
} else {
|
||||||
|
|
||||||
if (m_selfOnly) {
|
if (m_selfOnly) {
|
||||||
bool ret = checkCallsign(m_rfSource);
|
unsigned short srcId = layer3.getSourceUnitId();
|
||||||
if (!ret) {
|
if (srcId != m_id) {
|
||||||
LogMessage("NXDN, invalid access attempt from %10.10s", m_rfSource);
|
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RS_RF_REJECTED;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char cm = m_lastFICH.getCM();
|
data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA;
|
||||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
data[1U] = 0x00U;
|
||||||
m_rfDest = (unsigned char*)"ALL ";
|
|
||||||
|
CSync::addNXDNSync(data + 2U);
|
||||||
|
|
||||||
|
CNXDNLICH lich = m_rfLastLICH;
|
||||||
|
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
||||||
|
lich.encode(data + 2U);
|
||||||
|
|
||||||
|
CNXDNSACCH sacch;
|
||||||
|
sacch.setRAN(m_ran);
|
||||||
|
sacch.setStructure(NXDN_SR_SINGLE);
|
||||||
|
sacch.setData(SACCH_IDLE);
|
||||||
|
sacch.encode(data + 2U);
|
||||||
|
|
||||||
|
if (valid1) {
|
||||||
|
facch11.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
|
facch11.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
} else {
|
||||||
|
facch12.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
|
facch12.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrambler(data + 2U);
|
||||||
|
|
||||||
|
// writeNetwork(data, m_rfFrames, );
|
||||||
|
|
||||||
|
#if defined(DUMP_NXDN)
|
||||||
|
writeFile(data + 2U);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_duplex)
|
||||||
|
writeQueueRF(data);
|
||||||
|
|
||||||
|
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||||
|
m_rfFrames++;
|
||||||
|
if (m_rssi != 0U)
|
||||||
|
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
m_rfDest = m_rfPayload.getDest();
|
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
writeEndRF();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
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
|
||||||
|
m_rfLayer3 = layer3;
|
||||||
|
|
||||||
|
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||||
|
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||||
|
bool grp = m_rfLayer3.getIsGroup();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
unsigned char message[3U];
|
||||||
|
sacch.getData(message);
|
||||||
|
|
||||||
|
unsigned char structure = sacch.getStructure();
|
||||||
|
switch (structure) {
|
||||||
|
case NXDN_SR_1_4:
|
||||||
|
m_rfMask |= 0x01U;
|
||||||
|
m_rfLayer3.decode(message, 18U, 0U);
|
||||||
|
break;
|
||||||
|
case NXDN_SR_2_4:
|
||||||
|
m_rfMask |= 0x02U;
|
||||||
|
m_rfLayer3.decode(message, 18U, 18U);
|
||||||
|
break;
|
||||||
|
case NXDN_SR_3_4:
|
||||||
|
m_rfMask |= 0x04U;
|
||||||
|
m_rfLayer3.decode(message, 18U, 36U);
|
||||||
|
break;
|
||||||
|
case NXDN_SR_4_4:
|
||||||
|
m_rfMask |= 0x08U;
|
||||||
|
m_rfLayer3.decode(message, 18U, 54U);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rfMask != 0x0FU)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char messageType = m_rfLayer3.getMessageType();
|
||||||
|
if (messageType != NXDN_MESSAGE_TYPE_VCALL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||||
|
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||||
|
bool grp = m_rfLayer3.getIsGroup();
|
||||||
|
|
||||||
|
if (m_selfOnly) {
|
||||||
|
if (srcId != m_id) {
|
||||||
|
m_rfState = RS_RF_REJECTED;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_rfFrames = 0U;
|
m_rfFrames = 0U;
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
|
@ -225,292 +343,151 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
openFile();
|
openFile();
|
||||||
#endif
|
#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_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " ");
|
m_rfState = RS_RF_AUDIO;
|
||||||
LogMessage("NXDN, received RF header from %10.10s to %10.10s", m_rfSource, m_rfDest);
|
}
|
||||||
|
|
||||||
|
// if (m_rfState == RS_RF_AUDIO) {
|
||||||
|
// Regenerate the sync
|
||||||
CSync::addNXDNSync(data + 2U);
|
CSync::addNXDNSync(data + 2U);
|
||||||
|
|
||||||
CYSFFICH fich = m_lastFICH;
|
// Regenerate the LICH
|
||||||
|
CNXDNLICH lich;
|
||||||
|
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
|
||||||
|
lich.setFCT(usc);
|
||||||
|
lich.setOption(option);
|
||||||
|
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
||||||
|
lich.encode(data + 2U);
|
||||||
|
|
||||||
// Remove any DSQ information
|
// XXX Regenerate SACCH here
|
||||||
fich.setSQL(false);
|
|
||||||
fich.setSQ(0U);
|
// Regenerate the audio and interpret the FACCH1 data
|
||||||
fich.encode(data + 2U);
|
unsigned char voiceMode = m_rfLayer3.getCallOptions() & 0x07U;
|
||||||
|
|
||||||
|
if (option == NXDN_LICH_STEAL_NONE) {
|
||||||
|
CAMBEFEC ambe;
|
||||||
|
unsigned int errors = 0U;
|
||||||
|
if (voiceMode == NXDN_VOICE_CALL_OPTION_9600_EFR) {
|
||||||
|
errors += ambe.regenerateIMBE(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES);
|
||||||
|
errors += ambe.regenerateIMBE(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 18U);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 288U;
|
||||||
|
m_display->writeNXDNBER(float(errors) / 2.88F);
|
||||||
|
LogDebug("NXDN, EFR, AMBE FEC %u/288 (%.1f%%)", errors, float(errors) / 2.88F);
|
||||||
|
} else {
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES);
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 9U);
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 18U);
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 27U);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 188U;
|
||||||
|
m_display->writeNXDNBER(float(errors) / 1.88F);
|
||||||
|
LogDebug("NXDN, EHR, AMBE FEC %u/188 (%.1f%%)", errors, float(errors) / 1.88F);
|
||||||
|
}
|
||||||
|
} else if (option == NXDN_LICH_STEAL_FACCH1_1) {
|
||||||
|
CNXDNFACCH1 facch1;
|
||||||
|
bool valid = facch1.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
|
if (valid)
|
||||||
|
facch1.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
|
|
||||||
|
CAMBEFEC ambe;
|
||||||
|
unsigned int errors = 0U;
|
||||||
|
if (voiceMode == NXDN_VOICE_CALL_OPTION_9600_EFR) {
|
||||||
|
errors += ambe.regenerateIMBE(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 18U);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 144U;
|
||||||
|
m_display->writeNXDNBER(float(errors) / 1.44F);
|
||||||
|
LogDebug("NXDN, EFR, AMBE FEC %u/144 (%.1f%%)", errors, float(errors) / 1.44F);
|
||||||
|
} else {
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 18U);
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 27U);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 94U;
|
||||||
|
m_display->writeNXDNBER(float(errors) / 0.94F);
|
||||||
|
LogDebug("NXDN, EHR, AMBE FEC %u/94 (%.1f%%)", errors, float(errors) / 0.94F);
|
||||||
|
}
|
||||||
|
} else if (option == NXDN_LICH_STEAL_FACCH1_2) {
|
||||||
|
CAMBEFEC ambe;
|
||||||
|
unsigned int errors = 0U;
|
||||||
|
if (voiceMode == NXDN_VOICE_CALL_OPTION_9600_EFR) {
|
||||||
|
errors += ambe.regenerateIMBE(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 144U;
|
||||||
|
m_display->writeNXDNBER(float(errors) / 1.44F);
|
||||||
|
LogDebug("NXDN, EFR, AMBE FEC %u/144 (%.1f%%)", errors, float(errors) / 1.44F);
|
||||||
|
} else {
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES);
|
||||||
|
errors += ambe.regenerateDMR(data + 2U + NXDN_FSW_LICH_SACCH_LENGTH_BYTES + 9U);
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 94U;
|
||||||
|
m_display->writeNXDNBER(float(errors) / 0.94F);
|
||||||
|
LogDebug("NXDN, EHR, AMBE FEC %u/94 (%.1f%%)", errors, float(errors) / 0.94F);
|
||||||
|
}
|
||||||
|
|
||||||
|
CNXDNFACCH1 facch1;
|
||||||
|
bool valid = facch1.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
if (valid)
|
||||||
|
facch1.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
} else {
|
||||||
|
CNXDNFACCH1 facch11;
|
||||||
|
bool valid1 = facch11.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
|
if (valid1)
|
||||||
|
facch11.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||||
|
|
||||||
|
CNXDNFACCH1 facch12;
|
||||||
|
bool valid2 = facch12.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
if (valid2)
|
||||||
|
facch12.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
scrambler(data + 2U);
|
||||||
|
|
||||||
|
// writeNetwork(data, m_rfFrames, );
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex)
|
||||||
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
writeQueueRF(data);
|
writeQueueRF(data);
|
||||||
}
|
|
||||||
|
|
||||||
m_rfFrames++;
|
m_rfFrames++;
|
||||||
|
|
||||||
m_display->writeFusionRSSI(m_rssi);
|
m_display->writeNXDNRSSI(m_rssi);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (valid && fi == YSF_FI_TERMINATOR) {
|
|
||||||
if (m_rfState == RS_RF_REJECTED) {
|
|
||||||
m_rfPayload.reset();
|
|
||||||
m_rfSource = NULL;
|
|
||||||
m_rfDest = NULL;
|
|
||||||
m_rfState = RS_RF_LISTENING;
|
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
|
||||||
m_rfPayload.processHeaderData(data + 2U);
|
|
||||||
|
|
||||||
CSync::addNXDNSync(data + 2U);
|
|
||||||
|
|
||||||
CYSFFICH fich = m_lastFICH;
|
|
||||||
|
|
||||||
// Remove any DSQ information
|
|
||||||
fich.setSQL(false);
|
|
||||||
fich.setSQ(0U);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
|
|
||||||
data[0U] = TAG_EOT;
|
|
||||||
data[1U] = 0x00U;
|
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
|
||||||
writeFile(data + 2U);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_duplex) {
|
|
||||||
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
writeQueueRF(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rfFrames++;
|
|
||||||
|
|
||||||
|
#ifdef notdef
|
||||||
|
// Process end of audio here
|
||||||
|
if (endofdata) {
|
||||||
|
if (m_rfState == RS_RF_AUDIO) {
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
m_rfState = RS_RF_LISTENING;
|
||||||
// If valid is false, update the m_lastFICH for this transmission
|
m_rfMask = 0x00U;
|
||||||
if (!valid) {
|
return false;
|
||||||
unsigned char ft = m_lastFICH.getFT();
|
|
||||||
unsigned char fn = m_lastFICH.getFN() + 1U;
|
|
||||||
|
|
||||||
if (fn > ft)
|
|
||||||
fn = 0U;
|
|
||||||
|
|
||||||
m_lastFICH.setFN(fn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSync::addNXDNSync(data + 2U);
|
|
||||||
|
|
||||||
unsigned char fn = m_lastFICH.getFN();
|
|
||||||
unsigned char dt = m_lastFICH.getDT();
|
|
||||||
|
|
||||||
switch (dt) {
|
|
||||||
case YSF_DT_VD_MODE1: {
|
|
||||||
m_rfPayload.processVDMode1Data(data + 2U, fn);
|
|
||||||
unsigned int errors = m_rfPayload.processVDMode1Audio(data + 2U);
|
|
||||||
m_rfErrs += errors;
|
|
||||||
m_rfBits += 235U;
|
|
||||||
m_display->writeFusionBER(float(errors) / 2.35F);
|
|
||||||
LogDebug("NXDN, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 2.35F);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case YSF_DT_VD_MODE2: {
|
|
||||||
m_rfPayload.processVDMode2Data(data + 2U, fn);
|
|
||||||
unsigned int errors = m_rfPayload.processVDMode2Audio(data + 2U);
|
|
||||||
m_rfErrs += errors;
|
|
||||||
m_rfBits += 135U;
|
|
||||||
m_display->writeFusionBER(float(errors) / 1.35F);
|
|
||||||
LogDebug("NXDN, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 1.35F);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
CYSFFICH fich = m_lastFICH;
|
|
||||||
|
|
||||||
// Remove any DSQ information
|
|
||||||
fich.setSQL(false);
|
|
||||||
fich.setSQ(0U);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
|
|
||||||
data[0U] = TAG_DATA;
|
|
||||||
data[1U] = 0x00U;
|
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
|
||||||
|
|
||||||
if (m_duplex) {
|
|
||||||
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
writeQueueRF(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
|
||||||
writeFile(data + 2U);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_rfFrames++;
|
|
||||||
|
|
||||||
m_display->writeFusionRSSI(m_rssi);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (valid && m_rfState == RS_RF_LISTENING) {
|
|
||||||
// Only use clean frames for late entry.
|
|
||||||
unsigned char fn = m_lastFICH.getFN();
|
|
||||||
unsigned char dt = m_lastFICH.getDT();
|
|
||||||
|
|
||||||
switch (dt) {
|
|
||||||
case YSF_DT_VD_MODE1:
|
|
||||||
valid = m_rfPayload.processVDMode1Data(data + 2U, fn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case YSF_DT_VD_MODE2:
|
|
||||||
valid = m_rfPayload.processVDMode2Data(data + 2U, fn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
valid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!valid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned char cm = m_lastFICH.getCM();
|
|
||||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
|
||||||
m_rfDest = (unsigned char*)"ALL ";
|
|
||||||
else
|
|
||||||
m_rfDest = m_rfPayload.getDest();
|
|
||||||
|
|
||||||
m_rfSource = m_rfPayload.getSource();
|
|
||||||
|
|
||||||
if (m_rfSource == NULL || m_rfDest == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_selfOnly) {
|
|
||||||
bool ret = checkCallsign(m_rfSource);
|
|
||||||
if (!ret) {
|
|
||||||
LogMessage("NXDN, invalid access attempt from %10.10s", m_rfSource);
|
|
||||||
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
|
|
||||||
|
|
||||||
// Build a new header and transmit it
|
|
||||||
unsigned char buffer[YSF_FRAME_LENGTH_BYTES + 2U];
|
|
||||||
|
|
||||||
CSync::addNXDNSync(buffer + 2U);
|
|
||||||
|
|
||||||
CYSFFICH fich = m_lastFICH;
|
|
||||||
fich.setFI(YSF_FI_HEADER);
|
|
||||||
fich.setSQL(false);
|
|
||||||
fich.setSQ(0U);
|
|
||||||
fich.encode(buffer + 2U);
|
|
||||||
|
|
||||||
unsigned char csd1[20U], csd2[20U];
|
|
||||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_rfSource, YSF_CALLSIGN_LENGTH);
|
|
||||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
|
||||||
|
|
||||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
|
||||||
memset(csd1 + 0U, '*', YSF_CALLSIGN_LENGTH);
|
|
||||||
else
|
|
||||||
memcpy(csd1 + 0U, m_rfDest, YSF_CALLSIGN_LENGTH);
|
|
||||||
|
|
||||||
CYSFPayload payload;
|
|
||||||
payload.writeHeader(buffer + 2U, csd1, csd2);
|
|
||||||
|
|
||||||
buffer[0U] = TAG_DATA;
|
|
||||||
buffer[1U] = 0x00U;
|
|
||||||
|
|
||||||
writeNetwork(buffer, m_rfFrames % 128U);
|
|
||||||
|
|
||||||
if (m_duplex) {
|
|
||||||
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
|
||||||
fich.encode(buffer + 2U);
|
|
||||||
writeQueueRF(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
|
||||||
writeFile(buffer + 2U);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " ");
|
|
||||||
LogMessage("NXDN, received RF late entry from %10.10s to %10.10s", m_rfSource, m_rfDest);
|
|
||||||
|
|
||||||
CSync::addNXDNSync(data + 2U);
|
|
||||||
|
|
||||||
fich = m_lastFICH;
|
|
||||||
|
|
||||||
// Remove any DSQ information
|
|
||||||
fich.setSQL(false);
|
|
||||||
fich.setSQ(0U);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
|
|
||||||
data[0U] = TAG_DATA;
|
|
||||||
data[1U] = 0x00U;
|
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
|
||||||
|
|
||||||
if (m_duplex) {
|
|
||||||
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
|
||||||
fich.encode(data + 2U);
|
|
||||||
writeQueueRF(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
|
||||||
writeFile(data + 2U);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_rfFrames++;
|
|
||||||
|
|
||||||
m_display->writeFusionRSSI(m_rssi);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
{
|
{
|
||||||
if (option == NXDN_LICH_STEAL_FACCH) {
|
CNXDNUDCH udch;
|
||||||
CNXDNFACCH2 facch2;
|
bool valid = udch.decode(data + 2U);
|
||||||
bool valid = facch2.decode(data + 2U);
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
unsigned char ran = facch2.getRAN();
|
unsigned char ran = udch.getRAN();
|
||||||
if (ran != m_ran && ran != 0U)
|
if (ran != m_ran && ran != 0U)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -522,40 +499,15 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
CNXDNLICH lich;
|
CNXDNLICH lich;
|
||||||
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
|
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
|
||||||
lich.setFCT(NXDN_LICH_USC_UDCH);
|
lich.setFCT(NXDN_LICH_USC_UDCH);
|
||||||
lich.setOption(NXDN_LICH_STEAL_FACCH);
|
lich.setOption(option);
|
||||||
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
|
||||||
lich.encode(data + 2U);
|
|
||||||
|
|
||||||
facch2.setRAN(m_ran);
|
|
||||||
facch2.encode(data + 2U);
|
|
||||||
|
|
||||||
writeQueueNet(data);
|
|
||||||
|
|
||||||
if (m_duplex)
|
|
||||||
writeQueueRF(data);
|
|
||||||
#if defined(DUMP_NXDN)
|
|
||||||
writeFile(data + 2U);
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CNXDNUDCH udch;
|
|
||||||
bool valid = udch.decode(data + 2U);
|
|
||||||
if (valid) {
|
|
||||||
data[0U] = TAG_DATA;
|
|
||||||
data[1U] = 0x00U;
|
|
||||||
|
|
||||||
CSync::addNXDNSync(data + 2U);
|
|
||||||
|
|
||||||
CNXDNLICH lich;
|
|
||||||
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
|
|
||||||
lich.setFCT(NXDN_LICH_USC_UDCH);
|
|
||||||
lich.setOption(NXDN_LICH_STEAL_NONE);
|
|
||||||
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
||||||
lich.encode(data + 2U);
|
lich.encode(data + 2U);
|
||||||
|
|
||||||
|
udch.setRAN(m_ran);
|
||||||
udch.encode(data + 2U);
|
udch.encode(data + 2U);
|
||||||
|
|
||||||
|
scrambler(data + 2U);
|
||||||
|
|
||||||
writeQueueNet(data);
|
writeQueueNet(data);
|
||||||
|
|
||||||
if (m_duplex)
|
if (m_duplex)
|
||||||
|
@ -565,7 +517,6 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
unsigned char fi = m_lastFICH.getFI();
|
unsigned char fi = m_lastFICH.getFI();
|
||||||
|
@ -618,7 +569,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
writeNetwork(data, m_rfFrames);
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
|
@ -657,7 +608,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
data[0U] = TAG_EOT;
|
data[0U] = TAG_EOT;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
writeNetwork(data, m_rfFrames);
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
|
@ -707,7 +658,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
writeNetwork(data, m_rfFrames);
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
||||||
|
@ -749,6 +700,8 @@ void CNXDNControl::writeEndRF()
|
||||||
{
|
{
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RS_RF_LISTENING;
|
||||||
|
|
||||||
|
m_rfMask = 0x00U;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RS_NET_IDLE) {
|
||||||
|
@ -973,7 +926,7 @@ void CNXDNControl::writeQueueNet(const unsigned char *data)
|
||||||
m_queue.addData(data, len);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNControl::writeNetwork(const unsigned char *data, unsigned int count)
|
void CNXDNControl::writeNetwork(const unsigned char *data, unsigned int count, bool end)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
|
@ -983,7 +936,11 @@ void CNXDNControl::writeNetwork(const unsigned char *data, unsigned int count)
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_network->write(data + 2U, count, data[0U] == TAG_EOT);
|
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||||
|
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||||
|
bool grp = m_rfLayer3.getIsGroup();
|
||||||
|
|
||||||
|
m_network->write(data + 2U, srcId, grp, dstId, count % 256U, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNControl::scrambler(unsigned char* data) const
|
void CNXDNControl::scrambler(unsigned char* data) const
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "RSSIInterpolator.h"
|
#include "RSSIInterpolator.h"
|
||||||
#include "NXDNNetwork.h"
|
#include "NXDNNetwork.h"
|
||||||
#include "NXDNDefines.h"
|
#include "NXDNDefines.h"
|
||||||
|
#include "NXDNLayer3.h"
|
||||||
#include "NXDNLookup.h"
|
#include "NXDNLookup.h"
|
||||||
#include "RingBuffer.h"
|
#include "RingBuffer.h"
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
|
@ -68,7 +69,9 @@ private:
|
||||||
unsigned int m_rfBits;
|
unsigned int m_rfBits;
|
||||||
unsigned int m_netErrs;
|
unsigned int m_netErrs;
|
||||||
unsigned int m_netBits;
|
unsigned int m_netBits;
|
||||||
CNXDNLICH m_lastLICH;
|
CNXDNLICH m_rfLastLICH;
|
||||||
|
CNXDNLayer3 m_rfLayer3;
|
||||||
|
unsigned char m_rfMask;
|
||||||
unsigned char m_netN;
|
unsigned char m_netN;
|
||||||
CRSSIInterpolator* m_rssiMapper;
|
CRSSIInterpolator* m_rssiMapper;
|
||||||
unsigned char m_rssi;
|
unsigned char m_rssi;
|
||||||
|
@ -83,7 +86,7 @@ private:
|
||||||
|
|
||||||
void writeQueueRF(const unsigned char* data);
|
void writeQueueRF(const unsigned char* data);
|
||||||
void writeQueueNet(const unsigned char* data);
|
void writeQueueNet(const unsigned char* data);
|
||||||
void writeNetwork(const unsigned char* data, unsigned int count);
|
void writeNetwork(const unsigned char* data, unsigned int count, bool end);
|
||||||
void writeNetwork();
|
void writeNetwork();
|
||||||
|
|
||||||
void scrambler(unsigned char* data) const;
|
void scrambler(unsigned char* data) const;
|
||||||
|
|
|
@ -45,7 +45,7 @@ m_dp(NULL)
|
||||||
{
|
{
|
||||||
m_metrics1 = new uint16_t[16U];
|
m_metrics1 = new uint16_t[16U];
|
||||||
m_metrics2 = new uint16_t[16U];
|
m_metrics2 = new uint16_t[16U];
|
||||||
m_decisions = new uint64_t[180U];
|
m_decisions = new uint64_t[300U];
|
||||||
}
|
}
|
||||||
|
|
||||||
CNXDNConvolution::~CNXDNConvolution()
|
CNXDNConvolution::~CNXDNConvolution()
|
||||||
|
@ -98,7 +98,7 @@ void CNXDNConvolution::decode(uint8_t s0, uint8_t s1)
|
||||||
|
|
||||||
++m_dp;
|
++m_dp;
|
||||||
|
|
||||||
assert((m_dp - m_decisions) <= 180);
|
assert((m_dp - m_decisions) <= 300);
|
||||||
|
|
||||||
uint16_t* tmp = m_oldMetrics;
|
uint16_t* tmp = m_oldMetrics;
|
||||||
m_oldMetrics = m_newMetrics;
|
m_oldMetrics = m_newMetrics;
|
||||||
|
|
|
@ -66,4 +66,41 @@ const unsigned char NXDN_SR_3_4 = 1U;
|
||||||
const unsigned char NXDN_SR_2_4 = 2U;
|
const unsigned char NXDN_SR_2_4 = 2U;
|
||||||
const unsigned char NXDN_SR_1_4 = 3U;
|
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;
|
||||||
|
|
||||||
|
const unsigned char NXDN_VOICE_CALL_OPTION_HALF_DUPLEX = 0x00U;
|
||||||
|
const unsigned char NXDN_VOICE_CALL_OPTION_DUPLEX = 0x10U;
|
||||||
|
|
||||||
|
const unsigned char NXDN_VOICE_CALL_OPTION_4800_EHR = 0x00U;
|
||||||
|
const unsigned char NXDN_VOICE_CALL_OPTION_9600_EHR = 0x02U;
|
||||||
|
const unsigned char NXDN_VOICE_CALL_OPTION_9600_EFR = 0x03U;
|
||||||
|
|
||||||
|
const unsigned char NXDN_DATA_CALL_OPTION_HALF_DUPLEX = 0x00U;
|
||||||
|
const unsigned char NXDN_DATA_CALL_OPTION_DUPLEX = 0x10U;
|
||||||
|
|
||||||
|
const unsigned char NXDN_DATA_CALL_OPTION_4800 = 0x00U;
|
||||||
|
const unsigned char NXDN_DATA_CALL_OPTION_9600 = 0x02U;
|
||||||
|
|
||||||
|
const unsigned char SACCH_IDLE[] = { NXDN_MESSAGE_TYPE_IDLE, 0x00U, 0x00U };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
104
NXDNFACCH1.cpp
104
NXDNFACCH1.cpp
|
@ -28,6 +28,22 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
const unsigned int INTERLEAVE_TABLE[] = {
|
||||||
|
0U, 9U, 18U, 27U, 36U, 45U, 54U, 63U, 72U, 81U, 90U, 99U, 108U, 117U, 126U, 135U,
|
||||||
|
1U, 10U, 19U, 28U, 37U, 46U, 55U, 64U, 73U, 82U, 91U, 100U, 109U, 118U, 127U, 136U,
|
||||||
|
2U, 11U, 20U, 29U, 38U, 47U, 56U, 65U, 74U, 83U, 92U, 101U, 110U, 119U, 128U, 137U,
|
||||||
|
3U, 12U, 21U, 30U, 39U, 48U, 57U, 66U, 75U, 84U, 93U, 102U, 111U, 120U, 129U, 138U,
|
||||||
|
4U, 13U, 22U, 31U, 40U, 49U, 58U, 67U, 76U, 85U, 94U, 103U, 112U, 121U, 130U, 139U,
|
||||||
|
5U, 14U, 23U, 32U, 41U, 50U, 59U, 68U, 77U, 86U, 95U, 104U, 113U, 122U, 131U, 140U,
|
||||||
|
6U, 15U, 24U, 33U, 42U, 51U, 60U, 69U, 78U, 87U, 96U, 105U, 114U, 123U, 132U, 141U,
|
||||||
|
7U, 16U, 25U, 34U, 43U, 52U, 61U, 70U, 79U, 88U, 97U, 106U, 115U, 124U, 133U, 142U,
|
||||||
|
8U, 17U, 26U, 35U, 44U, 53U, 62U, 71U, 80U, 89U, 98U, 107U, 116U, 125U, 134U, 143U };
|
||||||
|
|
||||||
|
const unsigned int PUNCTURE_LIST[] = { 1U, 5U, 9U, 13U, 17U, 21U, 25U, 29U, 33U, 37U,
|
||||||
|
41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U, 73U, 77U,
|
||||||
|
81U, 85U, 89U, 93U, 97U, 101U, 105U, 109U, 113U, 117U,
|
||||||
|
121U, 125U, 129U, 133U, 137U, 141U};
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
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 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])
|
||||||
|
@ -51,16 +67,98 @@ CNXDNFACCH1::~CNXDNFACCH1()
|
||||||
delete[] m_data;
|
delete[] m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNXDNFACCH1::decode(const unsigned char* data)
|
bool CNXDNFACCH1::decode(const unsigned char* data, unsigned int offset)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
return true;
|
// CUtils::dump("NXDN, FACCH1 input", data, 18U);
|
||||||
|
|
||||||
|
unsigned char temp1[18U];
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < NXDN_FACCH1_LENGTH_BITS; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE[i] + offset;
|
||||||
|
bool b = READ_BIT1(data, n);
|
||||||
|
WRITE_BIT1(temp1, i, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CUtils::dump("NXDN, FACCH1 de-interleaved", temp1, 18U);
|
||||||
|
|
||||||
|
uint8_t temp2[192U];
|
||||||
|
|
||||||
|
unsigned int n = 0U;
|
||||||
|
unsigned int index = 0U;
|
||||||
|
for (unsigned int i = 0U; i < NXDN_FACCH1_LENGTH_BITS; i++) {
|
||||||
|
if (n == PUNCTURE_LIST[index]) {
|
||||||
|
temp2[n++] = 99U;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool b = READ_BIT1(temp1, i);
|
||||||
|
temp2[n++] = b ? 1U : 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNXDNConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
n = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 96U; i++) {
|
||||||
|
uint8_t s0 = temp2[n++];
|
||||||
|
uint8_t s1 = temp2[n++];
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.chainback(m_data, 92U);
|
||||||
|
|
||||||
|
CUtils::dump("NXDN, FACCH1 decoded", m_data, 12U);
|
||||||
|
|
||||||
|
return CNXDNCRC::checkCRC12(m_data, 80U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNFACCH1::encode(unsigned char* data) const
|
void CNXDNFACCH1::encode(unsigned char* data, unsigned int offset) const
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
|
unsigned char temp1[12U];
|
||||||
|
::memset(temp1, 0x00U, 12U);
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 80U; i++) {
|
||||||
|
bool b = READ_BIT1(m_data, i);
|
||||||
|
WRITE_BIT1(temp1, i, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
CNXDNCRC::encodeCRC12(temp1, 80U);
|
||||||
|
|
||||||
|
// CUtils::dump("NXDN, FACCH1 encoded with CRC", temp1, 12U);
|
||||||
|
|
||||||
|
unsigned char temp2[24U];
|
||||||
|
|
||||||
|
CNXDNConvolution conv;
|
||||||
|
conv.encode(temp1, temp2, 96U);
|
||||||
|
|
||||||
|
// CUtils::dump("NXDN, FACCH1 convolved", temp2, 24U);
|
||||||
|
|
||||||
|
unsigned char temp3[18U];
|
||||||
|
|
||||||
|
unsigned int n = 0U;
|
||||||
|
unsigned int index = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 192U; i++) {
|
||||||
|
if (i != PUNCTURE_LIST[index]) {
|
||||||
|
bool b = READ_BIT1(temp2, i);
|
||||||
|
WRITE_BIT1(temp3, n, b);
|
||||||
|
n++;
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CUtils::dump("NXDN, FACCH1 punctured", temp3, 18U);
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < NXDN_FACCH1_LENGTH_BITS; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE[i] + offset;
|
||||||
|
bool b = READ_BIT1(temp3, i);
|
||||||
|
WRITE_BIT1(data, n, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNFACCH1::getData(unsigned char* data) const
|
void CNXDNFACCH1::getData(unsigned char* data) const
|
||||||
|
|
|
@ -25,9 +25,10 @@ public:
|
||||||
CNXDNFACCH1();
|
CNXDNFACCH1();
|
||||||
~CNXDNFACCH1();
|
~CNXDNFACCH1();
|
||||||
|
|
||||||
bool decode(const unsigned char* data);
|
bool decode(const unsigned char* data, unsigned int offset);
|
||||||
|
|
||||||
|
void encode(unsigned char* data, unsigned int offset) const;
|
||||||
|
|
||||||
void encode(unsigned char* data) const;
|
|
||||||
void getData(unsigned char* data) const;
|
void getData(unsigned char* data) const;
|
||||||
|
|
||||||
void setData(const unsigned char* data);
|
void setData(const unsigned char* data);
|
||||||
|
|
|
@ -61,7 +61,7 @@ bool CNXDNLICH::decode(const unsigned char* bytes)
|
||||||
|
|
||||||
bool parity = b[7U] ^ b[6U] ^ b[5U] ^ b[4U];
|
bool parity = b[7U] ^ b[6U] ^ b[5U] ^ b[4U];
|
||||||
|
|
||||||
LogMessage("NXDN, LICH bits: %d%d %d%d %d%d %d - %d, parity: %d", b[7U] ? 1 : 0, b[6U] ? 1 : 0, b[5U] ? 1 : 0, b[4U] ? 1 : 0, b[3U] ? 1 : 0, b[2U] ? 1 : 0, b[1U] ? 1 : 0, b[0U] ? 1 : 0, parity ? 1 : 0);
|
// LogMessage("NXDN, LICH bits: %d%d %d%d %d%d %d - %d, parity: %d", b[7U] ? 1 : 0, b[6U] ? 1 : 0, b[5U] ? 1 : 0, b[4U] ? 1 : 0, b[3U] ? 1 : 0, b[2U] ? 1 : 0, b[1U] ? 1 : 0, b[0U] ? 1 : 0, parity ? 1 : 0);
|
||||||
|
|
||||||
if (parity != b[0U])
|
if (parity != b[0U])
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,11 +16,8 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "NXDNFACCH2.h"
|
|
||||||
|
|
||||||
#include "NXDNDefines.h"
|
#include "NXDNDefines.h"
|
||||||
#include "NXDNUDCH.h"
|
#include "NXDNLayer3.h"
|
||||||
#include "Utils.h"
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -32,78 +29,74 @@ const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04
|
||||||
#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 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])
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
CNXDNFACCH2::CNXDNFACCH2(const CNXDNFACCH2& facch2) :
|
CNXDNLayer3::CNXDNLayer3(const CNXDNLayer3& layer3) :
|
||||||
m_data(NULL)
|
m_data(NULL)
|
||||||
{
|
{
|
||||||
m_data = new unsigned char[23U];
|
m_data = new unsigned char[22U];
|
||||||
::memcpy(m_data, facch2.m_data, 23U);
|
::memcpy(m_data, layer3.m_data, 22U);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNXDNFACCH2::CNXDNFACCH2() :
|
CNXDNLayer3::CNXDNLayer3() :
|
||||||
m_data(NULL)
|
m_data(NULL)
|
||||||
{
|
{
|
||||||
m_data = new unsigned char[23U];
|
m_data = new unsigned char[22U];
|
||||||
|
::memset(m_data, 0x00U, 22U);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNXDNFACCH2::~CNXDNFACCH2()
|
CNXDNLayer3::~CNXDNLayer3()
|
||||||
{
|
{
|
||||||
delete[] m_data;
|
delete[] m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNXDNFACCH2::decode(const unsigned char* data)
|
void CNXDNLayer3::decode(const unsigned char* bytes, unsigned int length, unsigned int offset)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(bytes != NULL);
|
||||||
|
|
||||||
CNXDNUDCH udch;
|
for (unsigned int i = 0U; i < length; i++, offset++) {
|
||||||
bool valid = udch.decode(data);
|
bool b = READ_BIT1(bytes, offset);
|
||||||
if (!valid)
|
WRITE_BIT1(m_data, i, b);
|
||||||
return false;
|
}
|
||||||
|
|
||||||
udch.getData(m_data);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNFACCH2::encode(unsigned char* data) const
|
void CNXDNLayer3::encode(unsigned char* bytes, unsigned int length, unsigned int offset)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(bytes != NULL);
|
||||||
|
|
||||||
CNXDNUDCH udch;
|
for (unsigned int i = 0U; i < length; i++, offset++) {
|
||||||
|
bool b = READ_BIT1(m_data, i);
|
||||||
udch.setData(m_data);
|
WRITE_BIT1(bytes, offset, b);
|
||||||
|
}
|
||||||
udch.encode(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char CNXDNFACCH2::getRAN() const
|
unsigned char CNXDNLayer3::getMessageType() const
|
||||||
{
|
{
|
||||||
return m_data[0U] & 0x3FU;
|
return m_data[0U] & 0x3FU;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNFACCH2::getData(unsigned char* data) const
|
unsigned short CNXDNLayer3::getSourceUnitId() const
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
return (m_data[3U] << 8) | m_data[4U];
|
||||||
|
|
||||||
::memcpy(data, m_data + 1U, 22U);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNFACCH2::setRAN(unsigned char ran)
|
unsigned short CNXDNLayer3::getDestinationGroupId() const
|
||||||
{
|
{
|
||||||
m_data[0U] &= 0xC0U;
|
return (m_data[5U] << 8) | m_data[6U];
|
||||||
m_data[0U] |= ran;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNFACCH2::setData(const unsigned char* data)
|
bool CNXDNLayer3::getIsGroup() const
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
return (m_data[2U] & 0x80U) != 0x80U;
|
||||||
|
|
||||||
::memcpy(m_data + 1U, data, 22U);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CNXDNFACCH2& CNXDNFACCH2::operator=(const CNXDNFACCH2& facch2)
|
unsigned char CNXDNLayer3::getCallOptions() const
|
||||||
{
|
{
|
||||||
if (&facch2 != this)
|
return m_data[2U] & 0x1FU;
|
||||||
::memcpy(m_data, facch2.m_data, 23U);
|
}
|
||||||
|
|
||||||
|
CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3)
|
||||||
|
{
|
||||||
|
if (&layer3 != this)
|
||||||
|
::memcpy(m_data, layer3.m_data, 22U);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
|
@ -16,28 +16,26 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(NXDNFACCH2_H)
|
#if !defined(NXDNLayer3_H)
|
||||||
#define NXDNFACCH2_H
|
#define NXDNLayer3_H
|
||||||
|
|
||||||
class CNXDNFACCH2 {
|
class CNXDNLayer3 {
|
||||||
public:
|
public:
|
||||||
CNXDNFACCH2(const CNXDNFACCH2& facch);
|
CNXDNLayer3(const CNXDNLayer3& layer3);
|
||||||
CNXDNFACCH2();
|
CNXDNLayer3();
|
||||||
~CNXDNFACCH2();
|
~CNXDNLayer3();
|
||||||
|
|
||||||
bool decode(const unsigned char* data);
|
void decode(const unsigned char* bytes, unsigned int length, unsigned int offset = 0U);
|
||||||
|
|
||||||
void encode(unsigned char* data) const;
|
void encode(unsigned char* bytes, unsigned int length, unsigned int offset = 0U);
|
||||||
|
|
||||||
unsigned char getRAN() const;
|
unsigned char getMessageType() const;
|
||||||
|
unsigned short getSourceUnitId() const;
|
||||||
|
unsigned short getDestinationGroupId() const;
|
||||||
|
bool getIsGroup() const;
|
||||||
|
unsigned char getCallOptions() const;
|
||||||
|
|
||||||
void getData(unsigned char* data) const;
|
CNXDNLayer3& operator=(const CNXDNLayer3& layer3);
|
||||||
|
|
||||||
void setRAN(unsigned char ran);
|
|
||||||
|
|
||||||
void setData(const unsigned char* data);
|
|
||||||
|
|
||||||
CNXDNFACCH2& operator=(const CNXDNFACCH2& facch);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned char* m_data;
|
unsigned char* m_data;
|
|
@ -56,11 +56,11 @@ bool CNXDNNetwork::open()
|
||||||
return m_socket.open();
|
return m_socket.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNXDNNetwork::write(const unsigned char* data, unsigned int count, bool end)
|
bool CNXDNNetwork::write(const unsigned char* data, unsigned short src, bool grp, unsigned short dst, unsigned char cnt, bool end)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
unsigned char buffer[200U];
|
unsigned char buffer[100U];
|
||||||
|
|
||||||
buffer[0U] = 'N';
|
buffer[0U] = 'N';
|
||||||
buffer[1U] = 'X';
|
buffer[1U] = 'X';
|
||||||
|
@ -68,15 +68,23 @@ bool CNXDNNetwork::write(const unsigned char* data, unsigned int count, bool end
|
||||||
buffer[3U] = 'N';
|
buffer[3U] = 'N';
|
||||||
buffer[4U] = 'D';
|
buffer[4U] = 'D';
|
||||||
|
|
||||||
buffer[5U] = end ? 0x01U : 0x00U;
|
buffer[5U] = (src >> 8) & 0xFFU;
|
||||||
buffer[5U] |= (count & 0x7FU) << 1;
|
buffer[6U] = (src >> 8) & 0xFFU;
|
||||||
|
|
||||||
::memcpy(buffer + 6U, data, NXDN_FRAME_LENGTH_BYTES);
|
buffer[7U] = grp ? 0x01U : 0x00U;
|
||||||
|
buffer[7U] |= end ? 0x80U : 0x00U;
|
||||||
|
|
||||||
|
buffer[8U] = (dst >> 8) & 0xFFU;
|
||||||
|
buffer[9U] = (dst >> 8) & 0xFFU;
|
||||||
|
|
||||||
|
buffer[10U] = cnt;
|
||||||
|
|
||||||
|
::memcpy(buffer + 11U, data, NXDN_FRAME_LENGTH_BYTES);
|
||||||
|
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
CUtils::dump(1U, "NXDN Network Data Sent", buffer, 54U);
|
CUtils::dump(1U, "NXDN Network Data Sent", buffer, 59U);
|
||||||
|
|
||||||
return m_socket.write(buffer, 54U, m_address, m_port);
|
return m_socket.write(buffer, 59U, m_address, m_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNXDNNetwork::writePoll()
|
bool CNXDNNetwork::writePoll()
|
||||||
|
@ -131,19 +139,29 @@ void CNXDNNetwork::clock(unsigned int ms)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
CUtils::dump(1U, "NXDN Network Data Received", buffer, length);
|
CUtils::dump(1U, "NXDN Network Data Received", buffer, length);
|
||||||
|
|
||||||
m_buffer.addData(buffer, 54U);
|
m_buffer.addData(buffer, 59U);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CNXDNNetwork::read(unsigned char* data)
|
unsigned int CNXDNNetwork::read(unsigned char* data, unsigned short& src, bool& grp, unsigned short& dst, unsigned char& cnt, bool& end)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_buffer.isEmpty())
|
if (m_buffer.isEmpty())
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
||||||
m_buffer.getData(data, 54U);
|
unsigned char buffer[100U];
|
||||||
|
m_buffer.getData(buffer, 59U);
|
||||||
|
|
||||||
return 155U;
|
src = (buffer[5U] << 8) + buffer[6U];
|
||||||
|
grp = (buffer[7U] & 0x01U) == 0x01U;
|
||||||
|
end = (buffer[7U] & 0x80U) == 0x80U;
|
||||||
|
dst = (buffer[8U] << 8) + buffer[9U];
|
||||||
|
|
||||||
|
cnt = buffer[10U];
|
||||||
|
|
||||||
|
::memcpy(data, buffer + 11U, NXDN_FRAME_LENGTH_BYTES);
|
||||||
|
|
||||||
|
return NXDN_FRAME_LENGTH_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNNetwork::reset()
|
void CNXDNNetwork::reset()
|
||||||
|
|
|
@ -36,9 +36,9 @@ public:
|
||||||
|
|
||||||
void enable(bool enabled);
|
void enable(bool enabled);
|
||||||
|
|
||||||
bool write(const unsigned char* data, unsigned int count, bool end);
|
bool write(const unsigned char* data, unsigned short src, bool grp, unsigned short dst, unsigned char cnt, bool end);
|
||||||
|
|
||||||
unsigned int read(unsigned char* data);
|
unsigned int read(unsigned char* data, unsigned short& src, bool& grp, unsigned short& dst, unsigned char& cnt, bool& end);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ bool CNXDNSACCH::decode(const unsigned char* data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH input", data, 12U);
|
// CUtils::dump("NXDN, SACCH input", data, 12U);
|
||||||
|
|
||||||
unsigned char temp1[8U];
|
unsigned char temp1[8U];
|
||||||
|
|
||||||
|
@ -75,29 +75,22 @@ bool CNXDNSACCH::decode(const unsigned char* data)
|
||||||
WRITE_BIT1(temp1, i, b);
|
WRITE_BIT1(temp1, i, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH de-interleaved", temp1, 8U);
|
// CUtils::dump("NXDN, SACCH de-interleaved", temp1, 8U);
|
||||||
|
|
||||||
uint8_t temp2[72U];
|
uint8_t temp2[72U];
|
||||||
|
|
||||||
char text[500U];
|
|
||||||
::strcpy(text, "NXDN, SACCH de-punctured: ");
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
unsigned int n = 0U;
|
||||||
unsigned int index = 0U;
|
unsigned int index = 0U;
|
||||||
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
||||||
if (n == PUNCTURE_LIST[index]) {
|
if (n == PUNCTURE_LIST[index]) {
|
||||||
::strcat(text, "X, ");
|
|
||||||
temp2[n++] = 99U;
|
temp2[n++] = 99U;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool b = READ_BIT1(temp1, i);
|
bool b = READ_BIT1(temp1, i);
|
||||||
temp2[n++] = b ? 1U : 0U;
|
temp2[n++] = b ? 1U : 0U;
|
||||||
::strcat(text, b ? "1, " : "0, ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage(text);
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
CNXDNConvolution conv;
|
||||||
conv.start();
|
conv.start();
|
||||||
|
|
||||||
|
@ -111,7 +104,7 @@ bool CNXDNSACCH::decode(const unsigned char* data)
|
||||||
|
|
||||||
conv.chainback(m_data, 32U);
|
conv.chainback(m_data, 32U);
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH decoded", m_data, 5U);
|
CUtils::dump("NXDN, SACCH decoded", m_data, 4U);
|
||||||
|
|
||||||
return CNXDNCRC::checkCRC6(m_data, 26U);
|
return CNXDNCRC::checkCRC6(m_data, 26U);
|
||||||
}
|
}
|
||||||
|
@ -130,14 +123,14 @@ void CNXDNSACCH::encode(unsigned char* data) const
|
||||||
|
|
||||||
CNXDNCRC::encodeCRC6(temp1, 26U);
|
CNXDNCRC::encodeCRC6(temp1, 26U);
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 5U);
|
CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 4U);
|
||||||
|
|
||||||
unsigned char temp2[9U];
|
unsigned char temp2[8U];
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
CNXDNConvolution conv;
|
||||||
conv.encode(temp1, temp2, 36U);
|
conv.encode(temp1, temp2, 36U);
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH convolved", temp2, 9U);
|
// CUtils::dump("NXDN, SACCH convolved", temp2, 8U);
|
||||||
|
|
||||||
unsigned char temp3[8U];
|
unsigned char temp3[8U];
|
||||||
|
|
||||||
|
@ -153,15 +146,13 @@ void CNXDNSACCH::encode(unsigned char* data) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH punctured", temp3, 8U);
|
// CUtils::dump("NXDN, SACCH punctured", temp3, 8U);
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
||||||
bool b = READ_BIT1(temp3, i);
|
bool b = READ_BIT1(temp3, i);
|
||||||
WRITE_BIT1(data, n, b);
|
WRITE_BIT1(data, n, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUtils::dump("NXDN, SACCH re-encoded", data, 12U);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char CNXDNSACCH::getRAN() const
|
unsigned char CNXDNSACCH::getRAN() const
|
||||||
|
|
136
NXDNUDCH.cpp
136
NXDNUDCH.cpp
|
@ -28,6 +28,43 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
const unsigned int INTERLEAVE_TABLE[] = {
|
||||||
|
0U, 29U, 58U, 87U, 116U, 145U, 174U, 203U, 232U, 261U, 290U, 319U,
|
||||||
|
1U, 30U, 59U, 88U, 117U, 146U, 175U, 204U, 233U, 262U, 291U, 320U,
|
||||||
|
2U, 31U, 60U, 89U, 118U, 147U, 176U, 205U, 234U, 263U, 292U, 321U,
|
||||||
|
3U, 32U, 61U, 90U, 119U, 148U, 177U, 206U, 235U, 264U, 293U, 322U,
|
||||||
|
4U, 33U, 62U, 91U, 120U, 149U, 178U, 207U, 236U, 265U, 294U, 323U,
|
||||||
|
5U, 34U, 63U, 92U, 121U, 150U, 179U, 208U, 237U, 266U, 295U, 324U,
|
||||||
|
6U, 35U, 64U, 93U, 122U, 151U, 180U, 209U, 238U, 267U, 296U, 325U,
|
||||||
|
7U, 36U, 65U, 94U, 123U, 152U, 181U, 210U, 239U, 268U, 297U, 326U,
|
||||||
|
8U, 37U, 66U, 95U, 124U, 153U, 182U, 211U, 240U, 269U, 298U, 327U,
|
||||||
|
9U, 38U, 67U, 96U, 125U, 154U, 183U, 212U, 241U, 270U, 299U, 328U,
|
||||||
|
10U, 39U, 68U, 97U, 126U, 155U, 184U, 213U, 242U, 271U, 300U, 329U,
|
||||||
|
11U, 40U, 69U, 98U, 127U, 156U, 185U, 214U, 243U, 272U, 301U, 330U,
|
||||||
|
12U, 41U, 70U, 99U, 128U, 157U, 186U, 215U, 244U, 273U, 302U, 331U,
|
||||||
|
13U, 42U, 71U, 100U, 129U, 158U, 187U, 216U, 245U, 274U, 303U, 332U,
|
||||||
|
14U, 43U, 72U, 101U, 130U, 159U, 188U, 217U, 246U, 275U, 304U, 333U,
|
||||||
|
15U, 44U, 73U, 102U, 131U, 160U, 189U, 218U, 247U, 276U, 305U, 334U,
|
||||||
|
16U, 45U, 74U, 103U, 132U, 161U, 190U, 219U, 248U, 277U, 306U, 335U,
|
||||||
|
17U, 46U, 75U, 104U, 133U, 162U, 191U, 220U, 249U, 278U, 307U, 336U,
|
||||||
|
18U, 47U, 76U, 105U, 134U, 163U, 192U, 221U, 250U, 279U, 308U, 337U,
|
||||||
|
19U, 48U, 77U, 106U, 135U, 164U, 193U, 222U, 251U, 280U, 309U, 338U,
|
||||||
|
20U, 49U, 78U, 107U, 136U, 165U, 194U, 223U, 252U, 281U, 310U, 339U,
|
||||||
|
21U, 50U, 79U, 108U, 137U, 166U, 195U, 224U, 253U, 282U, 311U, 340U,
|
||||||
|
22U, 51U, 80U, 109U, 138U, 167U, 196U, 225U, 254U, 283U, 312U, 341U,
|
||||||
|
23U, 52U, 81U, 110U, 139U, 168U, 197U, 226U, 255U, 284U, 313U, 342U,
|
||||||
|
24U, 53U, 82U, 111U, 140U, 169U, 198U, 227U, 256U, 285U, 314U, 343U,
|
||||||
|
25U, 54U, 83U, 112U, 141U, 170U, 199U, 228U, 257U, 286U, 315U, 344U,
|
||||||
|
26U, 55U, 84U, 113U, 142U, 171U, 200U, 229U, 258U, 287U, 316U, 345U,
|
||||||
|
27U, 56U, 85U, 114U, 143U, 172U, 201U, 230U, 259U, 288U, 317U, 346U,
|
||||||
|
28U, 57U, 86U, 115U, 144U, 173U, 202U, 231U, 260U, 289U, 318U, 347U };
|
||||||
|
|
||||||
|
const unsigned int PUNCTURE_LIST[] = { 3U, 11U, 17U, 25U, 31U, 39U, 45U, 53U, 59U, 67U,
|
||||||
|
73U, 81U, 87U, 95U, 101U, 109U, 115U, 123U, 129U, 137U,
|
||||||
|
143U, 151U, 157U, 165U, 171U, 179U, 185U, 193U, 199U, 207U,
|
||||||
|
213U, 221U, 227U, 235U, 241U, 249U, 255U, 263U, 269U, 277U,
|
||||||
|
283U, 291U, 297U, 305U, 311U, 319U, 325U, 333U, 339U, 347U };
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
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 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])
|
||||||
|
@ -55,26 +92,119 @@ bool CNXDNUDCH::decode(const unsigned char* data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
return true;
|
CUtils::dump("NXDN, UDCH/FACCH2 input", data, 44U);
|
||||||
|
|
||||||
|
unsigned char temp1[44U];
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
||||||
|
bool b = READ_BIT1(data, n);
|
||||||
|
WRITE_BIT1(temp1, i, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUtils::dump("NXDN, UDCH/FACCH2 de-interleaved", temp1, 44U);
|
||||||
|
|
||||||
|
uint8_t temp2[406U];
|
||||||
|
|
||||||
|
unsigned int n = 0U;
|
||||||
|
unsigned int index = 0U;
|
||||||
|
for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) {
|
||||||
|
if (n == PUNCTURE_LIST[index]) {
|
||||||
|
temp2[n++] = 99U;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool b = READ_BIT1(temp1, i);
|
||||||
|
temp2[n++] = b ? 1U : 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
CNXDNConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
n = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 203U; i++) {
|
||||||
|
uint8_t s0 = temp2[n++];
|
||||||
|
uint8_t s1 = temp2[n++];
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
conv.chainback(m_data, 199U);
|
||||||
|
|
||||||
|
CUtils::dump("NXDN, UDCH/FACCH2 decoded", m_data, 25U);
|
||||||
|
|
||||||
|
return CNXDNCRC::checkCRC15(m_data, 184U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNUDCH::encode(unsigned char* data) const
|
void CNXDNUDCH::encode(unsigned char* data) const
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
|
unsigned char temp1[25U];
|
||||||
|
::memset(temp1, 0x00U, 25U);
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 184U; i++) {
|
||||||
|
bool b = READ_BIT1(m_data, i);
|
||||||
|
WRITE_BIT1(temp1, i, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
CNXDNCRC::encodeCRC15(temp1, 184U);
|
||||||
|
|
||||||
|
CUtils::dump("NXDN, UDCH/FACCH2 encoded with CRC", temp1, 25U);
|
||||||
|
|
||||||
|
unsigned char temp2[51U];
|
||||||
|
|
||||||
|
CNXDNConvolution conv;
|
||||||
|
conv.encode(temp1, temp2, 203U);
|
||||||
|
|
||||||
|
CUtils::dump("NXDN, UDCH/FACCH2 convolved", temp2, 51U);
|
||||||
|
|
||||||
|
unsigned char temp3[44U];
|
||||||
|
|
||||||
|
unsigned int n = 0U;
|
||||||
|
unsigned int index = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 406U; i++) {
|
||||||
|
if (i != PUNCTURE_LIST[index]) {
|
||||||
|
bool b = READ_BIT1(temp2, i);
|
||||||
|
WRITE_BIT1(temp3, n, b);
|
||||||
|
n++;
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CUtils::dump("NXDN, UDCH/FACCH2 punctured", temp3, 44U);
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
||||||
|
bool b = READ_BIT1(temp3, i);
|
||||||
|
WRITE_BIT1(data, n, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CNXDNUDCH::getRAN() const
|
||||||
|
{
|
||||||
|
return m_data[0U] & 0x3FU;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNUDCH::getData(unsigned char* data) const
|
void CNXDNUDCH::getData(unsigned char* data) const
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
::memcpy(data, m_data, 23U);
|
::memcpy(data, m_data + 1U, 22U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNXDNUDCH::setRAN(unsigned char ran)
|
||||||
|
{
|
||||||
|
m_data[0U] &= 0xC0U;
|
||||||
|
m_data[0U] |= ran;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNUDCH::setData(const unsigned char* data)
|
void CNXDNUDCH::setData(const unsigned char* data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
::memcpy(m_data, data, 23U);
|
::memcpy(m_data + 1U, data, 22U);
|
||||||
}
|
}
|
||||||
|
|
||||||
CNXDNUDCH& CNXDNUDCH::operator=(const CNXDNUDCH& udch)
|
CNXDNUDCH& CNXDNUDCH::operator=(const CNXDNUDCH& udch)
|
||||||
|
|
|
@ -29,8 +29,12 @@ public:
|
||||||
|
|
||||||
void encode(unsigned char* data) const;
|
void encode(unsigned char* data) const;
|
||||||
|
|
||||||
|
unsigned char getRAN() const;
|
||||||
|
|
||||||
void getData(unsigned char* data) const;
|
void getData(unsigned char* data) const;
|
||||||
|
|
||||||
|
void setRAN(unsigned char ran);
|
||||||
|
|
||||||
void setData(const unsigned char* data);
|
void setData(const unsigned char* data);
|
||||||
|
|
||||||
CNXDNUDCH& operator=(const CNXDNUDCH& udch);
|
CNXDNUDCH& operator=(const CNXDNUDCH& udch);
|
||||||
|
|
Loading…
Reference in a new issue