Merge branch 'master' into mqtt

This commit is contained in:
Jonathan Naylor
2025-03-14 13:39:49 +00:00
102 changed files with 1621 additions and 1489 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2021,2023 Jonathan Naylor, G4KLX
* Copyright (C) 2015-2021,2023,2025 Jonathan Naylor, G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,8 +51,8 @@ m_duplex(duplex),
m_remoteGateway(remoteGateway),
m_lookup(lookup),
m_queue(5000U, "NXDN Control"),
m_rfState(RS_RF_LISTENING),
m_netState(RS_NET_IDLE),
m_rfState(RPT_RF_STATE::LISTENING),
m_netState(RPT_NET_STATE::IDLE),
m_rfTimeoutTimer(1000U, timeout),
m_netTimeoutTimer(1000U, timeout),
m_packetTimer(1000U, 0U, 200U),
@@ -89,14 +89,14 @@ CNXDNControl::~CNXDNControl()
bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
{
assert(data != NULL);
assert(data != nullptr);
if (!m_enabled)
return false;
unsigned char type = data[0U];
if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) {
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::AUDIO)) {
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
bool grp = m_rfLayer3.getIsGroup();
unsigned short srcId = m_rfLayer3.getSourceUnitId();
@@ -113,13 +113,13 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
return false;
}
if (type == TAG_LOST && m_rfState == RS_RF_DATA) {
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::DATA)) {
writeEndRF();
return false;
}
if (type == TAG_LOST) {
m_rfState = RS_RF_LISTENING;
m_rfState = RPT_RF_STATE::LISTENING;
m_rfMask = 0x00U;
m_rfLayer3.reset();
return false;
@@ -187,7 +187,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
unsigned char ran = sacch.getRAN();
if (ran != m_ran && ran != 0U)
return false;
} else if (m_rfState == RS_RF_LISTENING) {
} else if (m_rfState == RPT_RF_STATE::LISTENING) {
return false;
}
@@ -211,17 +211,17 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
unsigned char type = layer3.getMessageType();
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
if (m_rfState != RS_RF_AUDIO) {
m_rfState = RS_RF_LISTENING;
if (m_rfState != RPT_RF_STATE::AUDIO) {
m_rfState = RPT_RF_STATE::LISTENING;
m_rfMask = 0x00U;
m_rfLayer3.reset();
return false;
}
} else if (type == NXDN_MESSAGE_TYPE_VCALL) {
if (m_rfState == RS_RF_LISTENING && m_selfOnly) {
if ((m_rfState == RPT_RF_STATE::LISTENING) && m_selfOnly) {
unsigned short srcId = layer3.getSourceUnitId();
if (srcId != m_id) {
m_rfState = RS_RF_REJECTED;
m_rfState = RPT_RF_STATE::REJECTED;
return true;
}
}
@@ -262,7 +262,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
scrambler(data + 2U);
writeNetwork(netData, data[0U] == TAG_EOT ? NNMT_VOICE_TRAILER : NNMT_VOICE_HEADER);
writeNetwork(netData, data[0U] == TAG_EOT ? NXDN_NETWORK_MESSAGE_TYPE::VOICE_TRAILER : NXDN_NETWORK_MESSAGE_TYPE::VOICE_HEADER);
if (m_duplex)
writeQueueRF(data);
@@ -313,7 +313,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
return true;
} else {
if (m_rfState == RS_RF_LISTENING) {
if (m_rfState == RPT_RF_STATE::LISTENING) {
CNXDNFACCH1 facch;
bool valid = false;
switch (option) {
@@ -390,7 +390,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
if (m_selfOnly) {
if (srcId != m_id) {
m_rfState = RS_RF_REJECTED;
m_rfState = RPT_RF_STATE::REJECTED;
return true;
}
}
@@ -418,7 +418,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
LogMessage("NXDN, received RF late entry from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
writeJSONRF("late_entry", srcId, source, grp, dstId);
m_rfState = RS_RF_AUDIO;
m_rfState = RPT_RF_STATE::AUDIO;
// Create a dummy start message
unsigned char start[NXDN_FRAME_LENGTH_BYTES + 2U];
@@ -460,14 +460,14 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
scrambler(start + 2U);
writeNetwork(netData, NNMT_VOICE_HEADER);
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::VOICE_HEADER);
if (m_duplex)
writeQueueRF(start);
}
}
if (m_rfState == RS_RF_AUDIO) {
if (m_rfState == RPT_RF_STATE::AUDIO) {
// Regenerate the sync
CSync::addNXDNSync(data + 2U);
@@ -563,7 +563,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
scrambler(data + 2U);
writeNetwork(netData, NNMT_VOICE_BODY);
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::VOICE_BODY);
if (m_duplex)
writeQueueRF(data);
@@ -580,7 +580,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
{
CNXDNUDCH udch;
bool validUDCH = udch.decode(data + 2U);
if (m_rfState == RS_RF_LISTENING && !validUDCH)
if ((m_rfState == RPT_RF_STATE::LISTENING) && !validUDCH)
return false;
if (validUDCH) {
@@ -599,7 +599,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
CNXDNLayer3 layer3;
layer3.decode(buffer, 184U);
if (m_rfState == RS_RF_LISTENING) {
if (m_rfState == RPT_RF_STATE::LISTENING) {
unsigned char type = layer3.getMessageType();
if (type != NXDN_MESSAGE_TYPE_DCALL_HDR)
return false;
@@ -628,7 +628,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
m_rfState = RS_RF_DATA;
}
if (m_rfState != RS_RF_DATA)
if (m_rfState != RPT_RF_STATE::DATA)
return false;
CSync::addNXDNSync(data + 2U);
@@ -662,13 +662,13 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
switch (type) {
case NXDN_MESSAGE_TYPE_DCALL_HDR:
writeNetwork(netData, NNMT_DATA_HEADER);
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::DATA_HEADER);
break;
case NXDN_MESSAGE_TYPE_TX_REL:
writeNetwork(netData, NNMT_DATA_TRAILER);
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::DATA_TRAILER);
break;
default:
writeNetwork(netData, NNMT_DATA_BODY);
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::DATA_BODY);
break;
}
@@ -693,7 +693,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
unsigned int CNXDNControl::readModem(unsigned char* data)
{
assert(data != NULL);
assert(data != nullptr);
if (m_queue.isEmpty())
return 0U;
@@ -708,7 +708,7 @@ unsigned int CNXDNControl::readModem(unsigned char* data)
void CNXDNControl::writeEndRF()
{
m_rfState = RS_RF_LISTENING;
m_rfState = RPT_RF_STATE::LISTENING;
m_rfMask = 0x00U;
m_rfLayer3.reset();
@@ -724,7 +724,7 @@ void CNXDNControl::writeEndRF()
void CNXDNControl::writeEndNet()
{
m_netState = RS_NET_IDLE;
m_netState = RPT_NET_STATE::IDLE;
m_netMask = 0x00U;
m_netLayer3.reset();
@@ -747,7 +747,7 @@ void CNXDNControl::writeNetwork()
if (!m_enabled)
return;
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
if ((m_rfState != RPT_RF_STATE::LISTENING) && (m_netState == RPT_NET_STATE::IDLE))
return;
m_networkWatchdog.start();
@@ -768,7 +768,7 @@ void CNXDNControl::writeNetwork()
layer3.setData(netData + 2U, 23U);
unsigned char type = layer3.getMessageType();
if (m_netState == RS_NET_IDLE) {
if (m_netState == RPT_NET_STATE::IDLE) {
if (type == NXDN_MESSAGE_TYPE_DCALL_HDR) {
unsigned short srcId = layer3.getSourceUnitId();
unsigned short dstId = layer3.getDestinationGroupId();
@@ -780,13 +780,13 @@ void CNXDNControl::writeNetwork()
LogMessage("NXDN, received network data header from %s to %s%u, %u blocks", source.c_str(), grp ? "TG " : "", dstId, frames);
writeJSONNet("start", srcId, source, grp, dstId, frames);
m_netState = RS_NET_DATA;
m_netState = RPT_NET_STATE::DATA;
} else {
return;
}
}
if (m_netState == RS_NET_DATA) {
if (m_netState == RPT_NET_STATE::DATA) {
data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA;
data[1U] = 0x00U;
@@ -814,9 +814,9 @@ void CNXDNControl::writeNetwork()
m_netLayer3.setData(netData + 5U + 0U, 10U);
unsigned char type = m_netLayer3.getMessageType();
if (type == NXDN_MESSAGE_TYPE_TX_REL && m_netState == RS_NET_IDLE)
if ((type == NXDN_MESSAGE_TYPE_TX_REL) && (m_netState == RPT_NET_STATE::IDLE))
return;
if (type == NXDN_MESSAGE_TYPE_VCALL && m_netState != RS_NET_IDLE)
if ((type == NXDN_MESSAGE_TYPE_VCALL) && (m_netState != RPT_NET_STATE::IDLE))
return;
CNXDNSACCH sacch;
@@ -855,14 +855,14 @@ void CNXDNControl::writeNetwork()
m_netTimeoutTimer.start();
m_packetTimer.start();
m_elapsed.start();
m_netState = RS_NET_AUDIO;
m_netState = RPT_NET_STATE::AUDIO;
m_netFrames = 1U;
} else {
CUtils::dump(2U, "NXDN, interesting non superblock network frame", netData, 33U);
return;
}
} else {
if (m_netState == RS_NET_IDLE) {
if (m_netState == RPT_NET_STATE::IDLE) {
unsigned char structure = (netData[1U] >> 6) & 0x03U;
switch (structure) {
case NXDN_SR_1_4:
@@ -907,7 +907,7 @@ void CNXDNControl::writeNetwork()
m_netTimeoutTimer.start();
m_packetTimer.start();
m_elapsed.start();
m_netState = RS_NET_AUDIO;
m_netState = RPT_NET_STATE::AUDIO;
m_netFrames = 1U;
// Create a dummy start message
@@ -992,13 +992,13 @@ void CNXDNControl::writeNetwork()
void CNXDNControl::clock(unsigned int ms)
{
if (m_network != NULL)
if (m_network != nullptr)
writeNetwork();
m_rfTimeoutTimer.clock(ms);
m_netTimeoutTimer.clock(ms);
if (m_netState == RS_NET_AUDIO) {
if (m_netState == RPT_NET_STATE::AUDIO) {
m_networkWatchdog.clock(ms);
if (m_networkWatchdog.hasExpired()) {
@@ -1011,9 +1011,9 @@ void CNXDNControl::clock(unsigned int ms)
void CNXDNControl::writeQueueRF(const unsigned char *data)
{
assert(data != NULL);
assert(data != nullptr);
if (m_netState != RS_NET_IDLE)
if (m_netState != RPT_NET_STATE::IDLE)
return;
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
@@ -1034,7 +1034,7 @@ void CNXDNControl::writeQueueRF(const unsigned char *data)
void CNXDNControl::writeQueueNet(const unsigned char *data)
{
assert(data != NULL);
assert(data != nullptr);
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired())
return;
@@ -1054,9 +1054,9 @@ void CNXDNControl::writeQueueNet(const unsigned char *data)
void CNXDNControl::writeNetwork(const unsigned char *data, NXDN_NETWORK_MESSAGE_TYPE type)
{
assert(data != NULL);
assert(data != nullptr);
if (m_network == NULL)
if (m_network == nullptr)
return;
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
@@ -1067,7 +1067,7 @@ void CNXDNControl::writeNetwork(const unsigned char *data, NXDN_NETWORK_MESSAGE_
void CNXDNControl::scrambler(unsigned char* data) const
{
assert(data != NULL);
assert(data != nullptr);
for (unsigned int i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++)
data[i] ^= SCRAMBLER[i];