Skip to content

Commit

Permalink
Add full FEC decoding to LDU1 and LDU2.
Browse files Browse the repository at this point in the history
  • Loading branch information
g4klx committed Sep 15, 2016
1 parent 9423fb2 commit 16ec0db
Show file tree
Hide file tree
Showing 17 changed files with 1,017 additions and 20 deletions.
2 changes: 2 additions & 0 deletions MMDVMHost.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
<ClInclude Include="P25Utils.h" />
<ClInclude Include="QR1676.h" />
<ClInclude Include="RingBuffer.h" />
<ClInclude Include="RS.h" />
<ClInclude Include="RS129.h" />
<ClInclude Include="SerialController.h" />
<ClInclude Include="SHA256.h" />
Expand Down Expand Up @@ -250,6 +251,7 @@
<ClCompile Include="P25NID.cpp" />
<ClCompile Include="P25Utils.cpp" />
<ClCompile Include="QR1676.cpp" />
<ClCompile Include="RS.cpp" />
<ClCompile Include="RS129.cpp" />
<ClCompile Include="SerialController.cpp" />
<ClCompile Include="SHA256.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions MMDVMHost.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@
<ClInclude Include="DMRNetwork.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RS.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="BPTC19696.cpp">
Expand Down Expand Up @@ -364,5 +367,8 @@
<ClCompile Include="DMRNetwork.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RS.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OBJECTS = \
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.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 Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o \
QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o \
QR1676.o RS.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o \
YSFNetwork.o YSFPayload.o

all: MMDVMHost
Expand Down
2 changes: 1 addition & 1 deletion Makefile.Pi.Adafruit
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OBJECTS = \
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.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 Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
P25Utils.o QR1676.o RS.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
YSFFICH.o YSFNetwork.o YSFPayload.o

all: MMDVMHost
Expand Down
2 changes: 1 addition & 1 deletion Makefile.Pi.HD44780
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OBJECTS = \
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.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 Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
P25Utils.o QR1676.o RS.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
YSFFICH.o YSFNetwork.o YSFPayload.o

all: MMDVMHost
Expand Down
2 changes: 1 addition & 1 deletion Makefile.Pi.OLED
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OBJECTS = \
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.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 OLED.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
P25Utils.o QR1676.o RS.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
YSFFICH.o YSFNetwork.o YSFPayload.o

all: MMDVMHost
Expand Down
2 changes: 1 addition & 1 deletion Makefile.Pi.PCF8574
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OBJECTS = \
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.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 Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
P25Utils.o QR1676.o RS.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
YSFFICH.o YSFNetwork.o YSFPayload.o

all: MMDVMHost
Expand Down
2 changes: 1 addition & 1 deletion Makefile.Solaris
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OBJECTS = \
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.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 Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o \
QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o \
QR1676.o RS.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o \
YSFNetwork.o YSFPayload.o

all: MMDVMHost
Expand Down
171 changes: 169 additions & 2 deletions P25Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#include "Log.h"
#include "Utils.h"

#include <cstdio>
#include <cassert>
#include <ctime>

// #define DUMP_P25

const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};

Expand All @@ -44,9 +46,14 @@ m_rfState(RS_RF_LISTENING),
m_netState(RS_NET_IDLE),
m_rfTimeout(1000U, timeout),
m_netTimeout(1000U, timeout),
m_networkWatchdog(1000U, 0U, 1500U),
m_rfFrames(0U),
m_rfBits(0U),
m_rfErrs(0U),
m_netFrames(0U),
m_netBits(0U),
m_netErrs(0U),
m_netLost(0U),
m_nid(),
m_audio(),
m_rfData(),
Expand All @@ -73,10 +80,14 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)

if (data[0U] == TAG_LOST) {
LogMessage("P25, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
m_display->clearP25();
if (m_netState == RS_NET_IDLE)
m_display->clearP25();
m_rfState = RS_RF_LISTENING;
m_rfTimeout.stop();
m_rfData.reset();
#if defined(DUMP_P25)
closeFile();
#endif
return false;
}

Expand Down Expand Up @@ -110,6 +121,13 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfBits = 1U;
m_rfTimeout.start();

#if defined(DUMP_P25)
openFile();
writeFile(data + 2U, len - 2U);
#endif

writeNetwork(data + 2U, P25_DUID_HEADER);

if (m_duplex) {
data[0U] = TAG_HEADER;
data[1U] = 0x00U;
Expand All @@ -123,6 +141,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfErrs = 0U;
m_rfBits = 1U;
m_rfTimeout.start();
#if defined(DUMP_P25)
openFile();
#endif
}

// Regenerate Sync
Expand All @@ -145,6 +166,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Add busy bits
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);

#if defined(DUMP_P25)
writeFile(data + 2U, len - 2U);
#endif

writeNetwork(data + 2U, P25_DUID_LDU1);

if (m_duplex) {
data[0U] = TAG_DATA;
data[1U] = 0x00U;
Expand Down Expand Up @@ -184,6 +211,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Add busy bits
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);

#if defined(DUMP_P25)
writeFile(data + 2U, len - 2U);
#endif

writeNetwork(data + 2U, P25_DUID_LDU2);

if (m_duplex) {
data[0U] = TAG_DATA;
data[1U] = 0x00U;
Expand All @@ -209,6 +242,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
LogMessage("P25, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
m_display->clearP25();

#if defined(DUMP_P25)
closeFile();
#endif

writeNetwork(data + 2U, P25_DUID_TERM_LC);

if (m_duplex) {
data[0U] = TAG_EOT;
data[1U] = 0x00U;
Expand All @@ -231,6 +270,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
LogMessage("P25, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
m_display->clearP25();

#if defined(DUMP_P25)
closeFile();
#endif

writeNetwork(data + 2U, P25_DUID_TERM);

if (m_duplex) {
data[0U] = TAG_EOT;
data[1U] = 0x00U;
Expand Down Expand Up @@ -258,10 +303,40 @@ unsigned int CP25Control::readModem(unsigned char* data)
return len;
}

void CP25Control::writeNetwork()
{
unsigned char data[200U];
unsigned int length = m_network->read(data, 200U);
if (length == 0U)
return;

if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
return;

m_networkWatchdog.start();


}

void CP25Control::clock(unsigned int ms)
{
if (m_network != NULL)
writeNetwork();

m_rfTimeout.clock(ms);
m_netTimeout.clock(ms);

if (m_netState == RS_NET_AUDIO) {
m_networkWatchdog.clock(ms);

if (m_networkWatchdog.hasExpired()) {
LogMessage("P25, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_netFrames) / 5.56F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
m_display->clearP25();
m_networkWatchdog.stop();
m_netState = RS_NET_IDLE;
m_netTimeout.stop();
}
}
}

void CP25Control::writeQueueRF(const unsigned char* data, unsigned int length)
Expand All @@ -283,6 +358,56 @@ void CP25Control::writeQueueRF(const unsigned char* data, unsigned int length)
m_queue.addData(data, len);
}

void CP25Control::writeQueueNet(const unsigned char* data, unsigned int length)
{
assert(data != NULL);

if (m_netTimeout.isRunning() && m_netTimeout.hasExpired())
return;

unsigned int space = m_queue.freeSpace();
if (space < (length + 1U)) {
LogError("P25, overflow in the P25 RF queue");
return;
}

unsigned char len = length;
m_queue.addData(&len, 1U);

m_queue.addData(data, len);
}

void CP25Control::writeNetwork(const unsigned char *data, unsigned char type)
{
assert(data != NULL);

if (m_network == NULL)
return;

if (m_rfTimeout.isRunning() && m_rfTimeout.hasExpired())
return;

switch (type)
{
case P25_DUID_HEADER:
m_network->writeHeader(data);
break;
case P25_DUID_LDU1:
m_network->writeLDU1(data);
break;
case P25_DUID_LDU2:
m_network->writeLDU2(data);
break;
case P25_DUID_TERM:
case P25_DUID_TERM_LC:
m_network->writeTerminator(data);
break;
default:
m_network->writeEnd();
break;
}
}

void CP25Control::addBusyBits(unsigned char* data, unsigned int length, bool b1, bool b2)
{
assert(data != NULL);
Expand All @@ -293,3 +418,45 @@ void CP25Control::addBusyBits(unsigned char* data, unsigned int length, bool b1,
WRITE_BIT(data, ss1Pos, b2);
}
}

bool CP25Control::openFile()
{
if (m_fp != NULL)
return true;

time_t t;
::time(&t);

struct tm* tm = ::localtime(&t);

char name[100U];
::sprintf(name, "P25_%04d%02d%02d_%02d%02d%02d.ambe", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);

m_fp = ::fopen(name, "wb");
if (m_fp == NULL)
return false;

::fwrite("P25", 1U, 3U, m_fp);

return true;
}

bool CP25Control::writeFile(const unsigned char* data, unsigned char length)
{
if (m_fp == NULL)
return false;

::fwrite(&length, 1U, 1U, m_fp);

::fwrite(data, 1U, length, m_fp);

return true;
}

void CP25Control::closeFile()
{
if (m_fp != NULL) {
::fclose(m_fp);
m_fp = NULL;
}
}
16 changes: 16 additions & 0 deletions P25Control.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "Modem.h"
#include "Timer.h"

#include <cstdio>

class CP25Control {
public:
CP25Control(unsigned int nac, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset);
Expand All @@ -54,16 +56,30 @@ class CP25Control {
RPT_NET_STATE m_netState;
CTimer m_rfTimeout;
CTimer m_netTimeout;
CTimer m_networkWatchdog;
unsigned int m_rfFrames;
unsigned int m_rfBits;
unsigned int m_rfErrs;
unsigned int m_netFrames;
unsigned int m_netBits;
unsigned int m_netErrs;
unsigned int m_netLost;
CP25NID m_nid;
CP25Audio m_audio;
CP25Data m_rfData;
CP25Data m_netData;
FILE* m_fp;

void writeQueueRF(const unsigned char* data, unsigned int length);
void writeQueueNet(const unsigned char* data, unsigned int length);
void writeNetwork(const unsigned char *data, unsigned char type);
void writeNetwork();

void addBusyBits(unsigned char* data, unsigned int length, bool b1, bool b2);

bool openFile();
bool writeFile(const unsigned char* data, unsigned char length);
void closeFile();
};

#endif
Loading

0 comments on commit 16ec0db

Please sign in to comment.