Start the network transmission.
This commit is contained in:
parent
e9b330f01e
commit
2bdef012c0
4 changed files with 183 additions and 60 deletions
132
P25Control.cpp
132
P25Control.cpp
|
@ -59,14 +59,21 @@ m_audio(),
|
|||
m_rfData(),
|
||||
m_netData(),
|
||||
m_lsd(),
|
||||
m_netLDU1(NULL),
|
||||
m_netLDU2(NULL),
|
||||
m_fp(NULL)
|
||||
{
|
||||
assert(display != NULL);
|
||||
assert(lookup != NULL);
|
||||
|
||||
m_netLDU1 = new unsigned char[9U * 25U];
|
||||
m_netLDU2 = new unsigned char[9U * 25U];
|
||||
}
|
||||
|
||||
CP25Control::~CP25Control()
|
||||
{
|
||||
delete[] m_netLDU1;
|
||||
delete[] m_netLDU2;
|
||||
}
|
||||
|
||||
bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||
|
@ -205,7 +212,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
bool grp = m_rfData.getGroup();
|
||||
unsigned int dst = m_rfData.getDest();
|
||||
std::string source = m_lookup->find(src);
|
||||
LogMessage("P25, received RF from %s to %s%u", source.c_str(), grp ? "TG" : "", dst);
|
||||
LogMessage("P25, received RF from %s to %s%u", source.c_str(), grp ? "TG " : "", dst);
|
||||
m_display->writeP25(source.c_str(), grp, dst, "R");
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
}
|
||||
|
@ -339,8 +346,8 @@ unsigned int CP25Control::readModem(unsigned char* data)
|
|||
|
||||
void CP25Control::writeNetwork()
|
||||
{
|
||||
unsigned char data[200U];
|
||||
unsigned int length = m_network->read(data, 200U);
|
||||
unsigned char data[100U];
|
||||
unsigned int length = m_network->read(data, 100U);
|
||||
if (length == 0U)
|
||||
return;
|
||||
|
||||
|
@ -349,7 +356,80 @@ void CP25Control::writeNetwork()
|
|||
|
||||
m_networkWatchdog.start();
|
||||
|
||||
|
||||
switch (data[0U]) {
|
||||
case 0x62U:
|
||||
::memcpy(m_netLDU1 + 0U, data, 22U);
|
||||
return;
|
||||
case 0x63U:
|
||||
::memcpy(m_netLDU1 + 25U, data, 13U);
|
||||
return;
|
||||
case 0x64U:
|
||||
::memcpy(m_netLDU1 + 50U, data, 17U);
|
||||
return;
|
||||
case 0x65U:
|
||||
::memcpy(m_netLDU1 + 75U, data, 17U);
|
||||
return;
|
||||
case 0x66U:
|
||||
::memcpy(m_netLDU1 + 100U, data, 17U);
|
||||
return;
|
||||
case 0x67U:
|
||||
::memcpy(m_netLDU1 + 125U, data, 17U);
|
||||
return;
|
||||
case 0x68U:
|
||||
::memcpy(m_netLDU1 + 150U, data, 17U);
|
||||
return;
|
||||
case 0x69U:
|
||||
::memcpy(m_netLDU1 + 175U, data, 17U);
|
||||
return;
|
||||
case 0x6AU:
|
||||
::memcpy(m_netLDU1 + 200U, data, 16U);
|
||||
if (m_netState != RS_NET_IDLE)
|
||||
createLDU1();
|
||||
return;
|
||||
case 0x6BU:
|
||||
::memcpy(m_netLDU2 + 0U, data, 22U);
|
||||
return;
|
||||
case 0x6CU:
|
||||
::memcpy(m_netLDU2 + 25U, data, 13U);
|
||||
return;
|
||||
case 0x6DU:
|
||||
::memcpy(m_netLDU2 + 50U, data, 17U);
|
||||
return;
|
||||
case 0x6EU:
|
||||
::memcpy(m_netLDU2 + 75U, data, 17U);
|
||||
return;
|
||||
case 0x6FU:
|
||||
::memcpy(m_netLDU2 + 100U, data, 17U);
|
||||
return;
|
||||
case 0x70U:
|
||||
::memcpy(m_netLDU2 + 125U, data, 17U);
|
||||
return;
|
||||
case 0x71U:
|
||||
::memcpy(m_netLDU2 + 150U, data, 17U);
|
||||
return;
|
||||
case 0x72U:
|
||||
::memcpy(m_netLDU2 + 175U, data, 17U);
|
||||
return;
|
||||
case 0x73U:
|
||||
::memcpy(m_netLDU2 + 200U, data, 16U);
|
||||
if (m_netState != RS_NET_IDLE) {
|
||||
m_netState = RS_NET_AUDIO;
|
||||
m_netTimeout.start();
|
||||
m_netBits = 1U;
|
||||
m_netErrs = 0U;
|
||||
m_netFrames = 0U;
|
||||
m_netLost = 0U;
|
||||
createHeader();
|
||||
createLDU1();
|
||||
}
|
||||
createLDU2();
|
||||
return;
|
||||
case 0x00U:
|
||||
createTerminator(data);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CP25Control::clock(unsigned int ms)
|
||||
|
@ -449,6 +529,50 @@ void CP25Control::addBusyBits(unsigned char* data, unsigned int length, bool b1,
|
|||
}
|
||||
}
|
||||
|
||||
void CP25Control::createHeader()
|
||||
{
|
||||
}
|
||||
|
||||
void CP25Control::createLDU1()
|
||||
{
|
||||
}
|
||||
|
||||
void CP25Control::createLDU2()
|
||||
{
|
||||
}
|
||||
|
||||
void CP25Control::createTerminator(const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (data[3U] != 0x25U)
|
||||
return;
|
||||
|
||||
unsigned char buffer[P25_TERM_FRAME_LENGTH_BYTES + 2U];
|
||||
::memset(buffer, 0x00U, P25_TERMLC_FRAME_LENGTH_BYTES + 2U);
|
||||
|
||||
buffer[0U] = TAG_EOT;
|
||||
buffer[1U] = 0x00U;
|
||||
|
||||
// Add the sync
|
||||
CSync::addP25Sync(buffer + 2U);
|
||||
|
||||
// Add the NID
|
||||
m_nid.encode(buffer + 2U, P25_DUID_TERM);
|
||||
|
||||
// Add busy bits
|
||||
addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
writeQueueNet(buffer, P25_TERM_FRAME_LENGTH_BYTES + 2U);
|
||||
|
||||
LogMessage("P25, network end of transmission, %.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_netTimeout.stop();
|
||||
m_networkWatchdog.stop();
|
||||
m_netState = RS_NET_IDLE;
|
||||
}
|
||||
|
||||
bool CP25Control::openFile()
|
||||
{
|
||||
if (m_fp != NULL)
|
||||
|
|
|
@ -71,6 +71,8 @@ private:
|
|||
CP25Data m_rfData;
|
||||
CP25Data m_netData;
|
||||
CP25LowSpeedData m_lsd;
|
||||
unsigned char* m_netLDU1;
|
||||
unsigned char* m_netLDU2;
|
||||
FILE* m_fp;
|
||||
|
||||
void writeQueueRF(const unsigned char* data, unsigned int length);
|
||||
|
@ -80,6 +82,11 @@ private:
|
|||
|
||||
void addBusyBits(unsigned char* data, unsigned int length, bool b1, bool b2);
|
||||
|
||||
void createHeader();
|
||||
void createLDU1();
|
||||
void createLDU2();
|
||||
void createTerminator(const unsigned char* data);
|
||||
|
||||
bool openFile();
|
||||
bool writeFile(const unsigned char* data, unsigned char length);
|
||||
void closeFile();
|
||||
|
|
|
@ -22,6 +22,24 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
const unsigned char CCS_PARITY[] = {
|
||||
0x00U, 0x39U, 0x72U, 0x4BU, 0xE4U, 0xDDU, 0x96U, 0xAFU, 0xF1U, 0xC8U, 0x83U, 0xBAU, 0x15U, 0x2CU, 0x67U, 0x5EU,
|
||||
0xDBU, 0xE2U, 0xA9U, 0x90U, 0x3FU, 0x06U, 0x4DU, 0x74U, 0x2AU, 0x13U, 0x58U, 0x61U, 0xCEU, 0xF7U, 0xBCU, 0x85U,
|
||||
0x8FU, 0xB6U, 0xFDU, 0xC4U, 0x6BU, 0x52U, 0x19U, 0x20U, 0x7EU, 0x47U, 0x0CU, 0x35U, 0x9AU, 0xA3U, 0xE8U, 0xD1U,
|
||||
0x54U, 0x6DU, 0x26U, 0x1FU, 0xB0U, 0x89U, 0xC2U, 0xFBU, 0xA5U, 0x9CU, 0xD7U, 0xEEU, 0x41U, 0x78U, 0x33U, 0x0AU,
|
||||
0x27U, 0x1EU, 0x55U, 0x6CU, 0xC3U, 0xFAU, 0xB1U, 0x88U, 0xD6U, 0xEFU, 0xA4U, 0x9DU, 0x32U, 0x0BU, 0x40U, 0x79U,
|
||||
0xFCU, 0xC5U, 0x8EU, 0xB7U, 0x18U, 0x21U, 0x6AU, 0x53U, 0x0DU, 0x34U, 0x7FU, 0xE9U, 0xD0U, 0x9BU, 0xA2U, 0xA8U,
|
||||
0x91U, 0xDAU, 0xE3U, 0x4CU, 0x75U, 0x3EU, 0x07U, 0x59U, 0x60U, 0x2BU, 0x12U, 0xBDU, 0x84U, 0xCFU, 0xF6U, 0x73U,
|
||||
0x4AU, 0x01U, 0x38U, 0x97U, 0xAEU, 0xE5U, 0xDCU, 0x82U, 0xBBU, 0xF0U, 0xC9U, 0x66U, 0x5FU, 0x14U, 0x2DU, 0x4EU,
|
||||
0x77U, 0x3CU, 0x05U, 0xAAU, 0x93U, 0xD8U, 0xE1U, 0xBFU, 0x86U, 0xCDU, 0xF4U, 0x5BU, 0x62U, 0x29U, 0x10U, 0x95U,
|
||||
0xACU, 0xE7U, 0xDEU, 0x71U, 0x48U, 0x03U, 0x3AU, 0x64U, 0x5DU, 0x16U, 0x2FU, 0x80U, 0xB9U, 0xF2U, 0xCBU, 0xC1U,
|
||||
0xF8U, 0xB3U, 0x8AU, 0x25U, 0x1CU, 0x57U, 0x6EU, 0x30U, 0x09U, 0x42U, 0x7BU, 0xD4U, 0xEDU, 0xA6U, 0x9FU, 0x1AU,
|
||||
0x23U, 0x68U, 0x51U, 0xFEU, 0xC7U, 0x8CU, 0xB5U, 0xEBU, 0xD2U, 0x99U, 0xA0U, 0x0FU, 0x36U, 0x7DU, 0x44U, 0x69U,
|
||||
0x50U, 0x1BU, 0x22U, 0x8DU, 0xB4U, 0xFFU, 0xC6U, 0x98U, 0xA1U, 0xEAU, 0xD3U, 0x7CU, 0x45U, 0x0EU, 0x37U, 0xB2U,
|
||||
0x8BU, 0xC0U, 0xF9U, 0x56U, 0x6FU, 0x24U, 0x1DU, 0x43U, 0x7AU, 0x31U, 0x08U, 0xA7U, 0x9EU, 0xD5U, 0xECU, 0xE6U,
|
||||
0xDFU, 0x94U, 0xADU, 0x02U, 0x3BU, 0x70U, 0x49U, 0x17U, 0x2EU, 0x65U, 0x5CU, 0xF3U, 0xCAU, 0x81U, 0xB8U, 0x3DU,
|
||||
0x04U, 0x4FU, 0x76U, 0xD9U, 0xE0U, 0xABU, 0x92U, 0xCCU, 0xF5U, 0xBEU, 0x87U, 0x28U, 0x11U, 0x5AU, 0x63U};
|
||||
|
||||
const unsigned int MAX_CCS_ERRS = 4U;
|
||||
|
||||
CP25LowSpeedData::CP25LowSpeedData()
|
||||
|
@ -32,7 +50,7 @@ CP25LowSpeedData::~CP25LowSpeedData()
|
|||
{
|
||||
}
|
||||
|
||||
void CP25LowSpeedData::process(unsigned char* data)
|
||||
void CP25LowSpeedData::process(unsigned char* data) const
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
|
@ -66,33 +84,7 @@ void CP25LowSpeedData::process(unsigned char* data)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned char CP25LowSpeedData::encode(unsigned char in)
|
||||
unsigned char CP25LowSpeedData::encode(unsigned char in) const
|
||||
{
|
||||
unsigned char result = 0x00U;
|
||||
|
||||
if ((in & 0x01U) == 0x01U)
|
||||
result ^= 0x39U;
|
||||
|
||||
if ((in & 0x02U) == 0x02U)
|
||||
result ^= 0x72U;
|
||||
|
||||
if ((in & 0x04U) == 0x04U)
|
||||
result ^= 0xE4U;
|
||||
|
||||
if ((in & 0x08U) == 0x08U)
|
||||
result ^= 0xF1U;
|
||||
|
||||
if ((in & 0x10U) == 0x10U)
|
||||
result ^= 0xDBU;
|
||||
|
||||
if ((in & 0x20U) == 0x20U)
|
||||
result ^= 0x8FU;
|
||||
|
||||
if ((in & 0x40U) == 0x40U)
|
||||
result ^= 0x27U;
|
||||
|
||||
if ((in & 0x80U) == 0x80U)
|
||||
result ^= 0x4EU;
|
||||
|
||||
return result;
|
||||
return CCS_PARITY[in];
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ public:
|
|||
CP25LowSpeedData();
|
||||
~CP25LowSpeedData();
|
||||
|
||||
void process(unsigned char* data);
|
||||
void process(unsigned char* data) const;
|
||||
|
||||
unsigned char encode(const unsigned char in);
|
||||
unsigned char encode(const unsigned char in) const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue