Merge branch 'master' into P25Changes

This commit is contained in:
Jonathan Naylor
2024-01-25 19:08:05 +00:00
222 changed files with 63510 additions and 13791 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2016-2019,2021,2024 by Jonathan Naylor G4KLX
* Copyright (C) 2018 by Bryan Biedenkapp <gatekeep@gmail.com> N2PLL
*
* This program is free software; you can redistribute it and/or modify
@@ -83,6 +83,7 @@ m_maxRSSI(0U),
m_minRSSI(0U),
m_aveRSSI(0U),
m_rssiCount(0U),
m_enabled(true),
m_fp(NULL)
{
assert(display != NULL);
@@ -118,13 +119,20 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
{
assert(data != NULL);
if (!m_enabled)
return false;
bool sync = data[1U] == 0x01U;
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
unsigned int dstId = m_rfData.getDstId();
std::string source = m_lookup->find(m_rfData.getSrcId());
if (m_rssi != 0U)
LogMessage("P25, transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
LogMessage("P25, transmission lost from %s to %s%u, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
else
LogMessage("P25, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
LogMessage("P25, transmission lost from %s to %s%u, %.1f seconds, BER: %.1f%%", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
LogMessage("P25, total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_rfFrames, m_rfBits, m_rfUndecodableLC, m_rfErrs, float(m_rfErrs * 100U) / float(m_rfBits));
@@ -315,7 +323,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfFrames++;
m_lastDUID = duid;
// Add busy bits
// Add busy bits, inbound busy
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
#if defined(DUMP_P25)
@@ -371,7 +379,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfFrames++;
m_lastDUID = duid;
// Add busy bits
// Add busy bits, inbound busy
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
#if defined(DUMP_P25)
@@ -404,14 +412,15 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
return false;
}
unsigned int srcId = m_rfData.getSrcId();
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
unsigned int dstId = m_rfData.getDstId();
std::string source = m_lookup->find(m_rfData.getSrcId());
unsigned char data[P25_TSDU_FRAME_LENGTH_BYTES + 2U];
switch (m_rfData.getLCF()) {
case P25_LCF_TSBK_CALL_ALERT:
LogMessage("P25, received RF TSDU transmission, CALL ALERT from %u to %u", srcId, dstId);
LogMessage("P25, received RF TSDU transmission, CALL ALERT from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Regenerate Sync
@@ -423,8 +432,8 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate TDULC Data
m_rfData.encodeTSDU(data + 2U);
// Add busy bits
addBusyBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, true, false);
// Add busy bits, inbound busy
addBusyBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, false, true);
// Set first busy bits to 1,1
setBusyBits(data + 2U, P25_SS0_START, true, true);
@@ -437,7 +446,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
}
break;
case P25_LCF_TSBK_ACK_RSP_FNE:
LogMessage("P25, received RF TSDU transmission, ACK RESPONSE FNE from %u to %u", srcId, dstId);
LogMessage("P25, received RF TSDU transmission, ACK RESPONSE FNE from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Regenerate Sync
@@ -449,8 +458,8 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate TDULC Data
m_rfData.encodeTSDU(data + 2U);
// Add busy bits
addBusyBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, true, false);
// Add busy bits, inbound busy
addBusyBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, false, true);
// Set first busy bits to 1,1
setBusyBits(data + 2U, P25_SS0_START, true, true);
@@ -481,18 +490,22 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate NID
m_nid.encode(data + 2U, P25_DUID_TERM);
// Add busy bits
// Add busy bits, inbound busy
addBusyBits(data + 2U, P25_TERM_FRAME_LENGTH_BITS, false, true);
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
unsigned int dstId = m_rfData.getDstId();
std::string source = m_lookup->find(m_rfData.getSrcId());
m_rfState = RS_RF_LISTENING;
m_rfTimeout.stop();
m_rfData.reset();
m_lastDUID = duid;
if (m_rssi != 0U)
LogMessage("P25, received RF end of voice transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
LogMessage("P25, received RF end of voice transmission from %s to %s%u, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
else
LogMessage("P25, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
LogMessage("P25, received RF end of voice transmission from %s to %s%u, %.1f seconds, BER: %.1f%%", source.c_str(), grp ? "TG " : "", dstId, float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
LogMessage("P25, total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_rfFrames, m_rfBits, m_rfUndecodableLC, m_rfErrs, float(m_rfErrs * 100U) / float(m_rfBits));
@@ -594,7 +607,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate NID
m_nid.encode(pdu + 2U, P25_DUID_PDU);
// Add busy bits
// Add busy bits, inbound busy
addBusyBits(pdu + 2U, newBitLength, false, true);
if (m_duplex) {
@@ -645,6 +658,9 @@ void CP25Control::writeNetwork()
if (length == 0U)
return;
if (!m_enabled)
return;
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
return;
@@ -948,7 +964,7 @@ void CP25Control::createRFHeader()
// Add the dummy header
m_rfData.encodeHeader(buffer + 2U);
// Add busy bits
// Add busy bits, inbound busy
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, false, true);
m_rfFrames = 0U;
@@ -1025,8 +1041,13 @@ void CP25Control::createNetHeader()
// Add busy bits
if (m_remoteGateway)
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, false, false);
// Add busy bits, inbound/outbound
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, true, false);
else if (m_duplex)
// Add busy bits, inbound idle
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, true, true);
else
// Add busy bits, inbound busy
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, false, true);
writeQueueNet(buffer, P25_HDR_FRAME_LENGTH_BYTES + 2U);
@@ -1069,8 +1090,13 @@ void CP25Control::createNetLDU1()
// Add busy bits
if (m_remoteGateway)
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, false);
// Add busy bits, inbound/outbound
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
else if (m_duplex)
// Add busy bits, inbound idle
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, true);
else
// Add busy bits, inbound busy
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
writeQueueNet(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
@@ -1117,8 +1143,13 @@ void CP25Control::createNetLDU2()
// Add busy bits
if (m_remoteGateway)
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, false);
// Add busy bits, inbound/outbound
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
else if (m_duplex)
// Add busy bits, inbound idle
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, true);
else
// Add busy bits, inbound busy
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
writeQueueNet(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
@@ -1144,13 +1175,20 @@ void CP25Control::createNetTerminator()
// Add busy bits
if (m_remoteGateway)
addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, false, false);
// Add busy bits, inbound/outbound
addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, true, false);
else if (m_duplex)
// Add busy bits, inbound idle
addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, true, true);
else
// Add busy bits, inbound busy
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", float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames);
std::string source = m_lookup->find(m_netData.getSrcId());
LogMessage("P25, network end of transmission from %s to %s%u, %.1f seconds, %u%% packet loss", source.c_str(), m_netData.getLCF() == P25_LCF_GROUP ? "TG " : "", m_netData.getDstId(), float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames);
m_display->clearP25();
m_netTimeout.stop();
@@ -1200,3 +1238,28 @@ void CP25Control::closeFile()
m_fp = NULL;
}
}
bool CP25Control::isBusy() const
{
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
}
void CP25Control::enable(bool enabled)
{
if (!enabled && m_enabled) {
m_queue.clear();
// Reset the RF section
m_rfState = RS_RF_LISTENING;
m_rfTimeout.stop();
m_rfData.reset();
// Reset the networking section
m_netTimeout.stop();
m_networkWatchdog.stop();
m_netData.reset();
m_netState = RS_NET_IDLE;
}
m_enabled = enabled;
}