refactor FSC (it was entirely just broken);

82-dvmbridge---implement-notch-filter-for-2175hz-trc-guard-tone
Bryan Biedenkapp 1 year ago
parent 88dcb0bc96
commit 19d8f2237f

@ -590,8 +590,10 @@ system:
jitter: 200 jitter: 200
# Timer which will reset local/remote call flags if frames aren't received longer than this time in ms # Timer which will reset local/remote call flags if frames aren't received longer than this time in ms
callTimeout: 200 callTimeout: 200
# Flag indicating when operating in V.24 UDP mode should the FSC protocol be used to negotiate connection. # Flag indicating when operating in V.24 UDP mode, the FSC protocol should be used to negotiate connection.
useFSC: false fsc: false
# Flag indicating when operating in V.24 UDP mode, this instance should initiate the FSC protocol handshake.
initiator: false
# Sets received the signal offset from DC. # Sets received the signal offset from DC.
rxDCOffset: 0 # Valid values between -128 and 128 rxDCOffset: 0 # Valid values between -128 and 128

@ -44,7 +44,7 @@ FSCACK::FSCACK(const uint8_t* data) : FSCMessage(data),
m_responseCode(FSCAckResponseCode::CONTROL_ACK), m_responseCode(FSCAckResponseCode::CONTROL_ACK),
m_respLength(0U) m_respLength(0U)
{ {
decode(data); FSCACK::decode(data);
} }
/* Decode a FSC ACK frame. */ /* Decode a FSC ACK frame. */

@ -42,7 +42,7 @@ FSCConnect::FSCConnect(const uint8_t* data) : FSCMessage(data),
m_fsHeartbeatPeriod(5U), m_fsHeartbeatPeriod(5U),
m_hostHeartbeatPeriod(5U) m_hostHeartbeatPeriod(5U)
{ {
decode(data); FSCConnect::decode(data);
} }
/* Decode a FSC connect frame. */ /* Decode a FSC connect frame. */

@ -36,7 +36,7 @@ FSCConnectResponse::FSCConnectResponse() : FSCResponse(),
FSCConnectResponse::FSCConnectResponse(const uint8_t* data) : FSCResponse(data), FSCConnectResponse::FSCConnectResponse(const uint8_t* data) : FSCResponse(data),
m_vcBasePort(0U) m_vcBasePort(0U)
{ {
decode(data); FSCConnectResponse::decode(data);
} }
/* Decode a FSC connect frame. */ /* Decode a FSC connect frame. */

@ -4,7 +4,7 @@
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL
* *
*/ */
#include "common/p25/dfsi/frames/fsc/FSCDisconnect.h" #include "common/p25/dfsi/frames/fsc/FSCDisconnect.h"
@ -34,5 +34,5 @@ FSCDisconnect::FSCDisconnect() : FSCMessage()
FSCDisconnect::FSCDisconnect(const uint8_t* data) : FSCMessage(data) FSCDisconnect::FSCDisconnect(const uint8_t* data) : FSCMessage(data)
{ {
decode(data); FSCMessage::decode(data);
} }

@ -4,7 +4,7 @@
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL
* *
*/ */
#include "common/p25/dfsi/frames/fsc/FSCHeartbeat.h" #include "common/p25/dfsi/frames/fsc/FSCHeartbeat.h"
@ -34,5 +34,5 @@ FSCHeartbeat::FSCHeartbeat() : FSCMessage()
FSCHeartbeat::FSCHeartbeat(const uint8_t* data) : FSCMessage(data) FSCHeartbeat::FSCHeartbeat(const uint8_t* data) : FSCMessage(data)
{ {
decode(data); /* stub */
} }

@ -82,7 +82,7 @@ namespace p25
/** /**
* @brief * @brief
*/ */
__PROTECTED_READONLY_PROPERTY(uint8_t, correlationTag, CorrelationTag); __PROPERTY(uint8_t, correlationTag, CorrelationTag);
}; };
} // namespace fsc } // namespace fsc
} // namespace frames } // namespace frames

@ -7,7 +7,7 @@
* @package DVM / Modem Host Software * @package DVM / Modem Host Software
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
* Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2017-2025 Bryan Biedenkapp, N2PLL
* *
*/ */
#include "Defines.h" #include "Defines.h"
@ -461,8 +461,9 @@ bool Host::createModem()
bool rtrt = dfsiParams["rtrt"].as<bool>(true); bool rtrt = dfsiParams["rtrt"].as<bool>(true);
bool diu = dfsiParams["diu"].as<bool>(true); bool diu = dfsiParams["diu"].as<bool>(true);
uint16_t jitter = dfsiParams["jitter"].as<uint16_t>(200U); uint16_t jitter = dfsiParams["jitter"].as<uint16_t>(200U);
bool useFSCForUDP = dfsiParams["useFSC"].as<bool>(false);
uint16_t dfsiCallTimeout = dfsiParams["callTimeout"].as<uint16_t>(200U); uint16_t dfsiCallTimeout = dfsiParams["callTimeout"].as<uint16_t>(200U);
bool useFSCForUDP = dfsiParams["fsc"].as<bool>(false);
bool fscInitiator = dfsiParams["initiator"].as<bool>(false);
// clamp fifo sizes // clamp fifo sizes
if (dmrFifoLength < DMR_TX_BUFFER_LEN) { if (dmrFifoLength < DMR_TX_BUFFER_LEN) {
@ -580,6 +581,7 @@ bool Host::createModem()
LogInfo(" DFSI Jitter Size: %u ms", jitter); LogInfo(" DFSI Jitter Size: %u ms", jitter);
if (g_remoteModemMode) { if (g_remoteModemMode) {
LogInfo(" DFSI Use FSC: %s", useFSCForUDP ? "yes" : "no"); LogInfo(" DFSI Use FSC: %s", useFSCForUDP ? "yes" : "no");
LogInfo(" DFSI FSC Initiator: %s", fscInitiator ? "yes" : "no");
} }
} }
@ -594,9 +596,10 @@ bool Host::createModem()
if (modemMode == MODEM_MODE_DFSI) { if (modemMode == MODEM_MODE_DFSI) {
yaml::Node networkConf = m_conf["network"]; yaml::Node networkConf = m_conf["network"];
uint32_t id = networkConf["id"].as<uint32_t>(1000U); uint32_t id = networkConf["id"].as<uint32_t>(1000U);
modemPort = new port::specialized::V24UDPPort(id, g_remoteAddress, g_remotePort, 0U, useFSCForUDP, debug);
if (useFSCForUDP) { if (useFSCForUDP) {
modemPort = new port::specialized::V24UDPPort(id, g_remoteAddress, g_remotePort + 1U, g_remotePort, useFSCForUDP, debug); modemPort = new port::specialized::V24UDPPort(id, g_remoteAddress, g_remotePort + 1U, g_remotePort, true, fscInitiator, debug);
} else {
modemPort = new port::specialized::V24UDPPort(id, g_remoteAddress, g_remotePort, 0U, false, false, debug);
} }
m_udpDSFIRemotePort = modemPort; m_udpDSFIRemotePort = modemPort;
} else { } else {

@ -50,7 +50,7 @@ std::mutex V24UDPPort::m_bufferMutex;
/* Initializes a new instance of the V24UDPPort class. */ /* Initializes a new instance of the V24UDPPort class. */
V24UDPPort::V24UDPPort(uint32_t peerId, const std::string& address, uint16_t modemPort, uint16_t controlPort, bool useFSC, bool debug) : V24UDPPort::V24UDPPort(uint32_t peerId, const std::string& address, uint16_t modemPort, uint16_t controlPort, bool useFSC, bool fscInitiator, bool debug) :
m_socket(nullptr), m_socket(nullptr),
m_localPort(modemPort), m_localPort(modemPort),
m_controlSocket(nullptr), m_controlSocket(nullptr),
@ -61,6 +61,8 @@ V24UDPPort::V24UDPPort(uint32_t peerId, const std::string& address, uint16_t mod
m_addrLen(0U), m_addrLen(0U),
m_ctrlAddrLen(0U), m_ctrlAddrLen(0U),
m_buffer(2000U, "UDP Port Ring Buffer"), m_buffer(2000U, "UDP Port Ring Buffer"),
m_fscInitiator(fscInitiator),
m_timeoutTimer(1000U, 30U),
m_reqConnectionTimer(1000U, 30U), m_reqConnectionTimer(1000U, 30U),
m_heartbeatTimer(1000U, 5U), m_heartbeatTimer(1000U, 5U),
m_reqConnectionToPeer(true), m_reqConnectionToPeer(true),
@ -120,7 +122,7 @@ void V24UDPPort::clock(uint32_t ms)
{ {
// if we have a FSC control socket // if we have a FSC control socket
if (m_controlSocket != nullptr) { if (m_controlSocket != nullptr) {
if (m_reqConnectionToPeer) { if (!m_establishedConnection && m_fscInitiator) {
if (!m_reqConnectionTimer.isRunning()) { if (!m_reqConnectionTimer.isRunning()) {
// make initial request // make initial request
writeConnect(); writeConnect();
@ -130,6 +132,7 @@ void V24UDPPort::clock(uint32_t ms)
if (m_reqConnectionTimer.isRunning() && m_reqConnectionTimer.hasExpired()) { if (m_reqConnectionTimer.isRunning() && m_reqConnectionTimer.hasExpired()) {
// make another request // make another request
writeConnect(); writeConnect();
m_reqConnectionTimer.start();
} }
} }
} }
@ -142,6 +145,16 @@ void V24UDPPort::clock(uint32_t ms)
} }
} }
m_timeoutTimer.clock(ms);
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
LogError(LOG_NET, "PEER %u connection to the DFSI endpoint has timed out, disconnected");
m_reqConnectionTimer.stop();
m_reqConnectionToPeer = true;
m_establishedConnection = false;
m_heartbeatTimer.stop();
m_timeoutTimer.stop();
}
processCtrlNetwork(); processCtrlNetwork();
} }
@ -268,7 +281,7 @@ void V24UDPPort::processCtrlNetwork()
// read message // read message
UInt8Array buffer = m_ctrlFrameQueue->read(length, address, addrLen); UInt8Array buffer = m_ctrlFrameQueue->read(length, address, addrLen);
if (length > 0) { if (length > 0) {
if (m_debug) //if (m_debug)
Utils::dump(1U, "FSC Control Network Message", buffer.get(), length); Utils::dump(1U, "FSC Control Network Message", buffer.get(), length);
V24PacketRequest* req = new V24PacketRequest(); V24PacketRequest* req = new V24PacketRequest();
@ -299,6 +312,8 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
::pthread_detach(req->thread); ::pthread_detach(req->thread);
#endif // defined(_WIN32) #endif // defined(_WIN32)
uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
V24UDPPort* network = static_cast<V24UDPPort*>(req->obj); V24UDPPort* network = static_cast<V24UDPPort*>(req->obj);
if (network == nullptr) { if (network == nullptr) {
delete req; delete req;
@ -306,7 +321,7 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
} }
if (req->length > 0) { if (req->length > 0) {
if (network->m_reqConnectionToPeer) { if (network->m_reqConnectionToPeer && !network->m_establishedConnection) {
// FSC_CONNECT response -- is ... strange // FSC_CONNECT response -- is ... strange
if (req->buffer[0] == 1U) { if (req->buffer[0] == 1U) {
network->m_reqConnectionToPeer = false; network->m_reqConnectionToPeer = false;
@ -319,91 +334,100 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
network->m_localPort = vcBasePort; network->m_localPort = vcBasePort;
network->createVCPort(vcBasePort); network->createVCPort(vcBasePort);
network->m_heartbeatTimer.start(); network->m_heartbeatTimer.start();
network->m_timeoutTimer.start();
uint8_t buffer[FSCConnectResponse::LENGTH]; LogMessage(LOG_MODEM, "Established DFSI FSC Connection, vcBasePort = %u", vcBasePort);
::memset(buffer, 0x00U, FSCConnectResponse::LENGTH);
resp.setVCBasePort(network->m_localPort);
resp.encode(buffer);
network->m_ctrlFrameQueue->write(buffer, FSCConnectResponse::LENGTH, network->m_controlAddr, network->m_ctrlAddrLen); if (req->buffer != nullptr)
delete[] req->buffer;
delete req;
return nullptr;
} }
} }
else
{ std::unique_ptr<FSCMessage> message = FSCMessage::createMessage(req->buffer);
std::unique_ptr<FSCMessage> message = FSCMessage::createMessage(req->buffer); if (message != nullptr) {
if (message != nullptr) { switch (message->getMessageId())
switch (message->getMessageId()) {
{ case FSCMessageType::FSC_ACK:
case FSCMessageType::FSC_ACK: {
FSCACK* ackMessage = static_cast<FSCACK*>(message.get());
switch (ackMessage->getResponseCode())
{ {
FSCACK* ackMessage = static_cast<FSCACK*>(message.get()); case FSCAckResponseCode::CONTROL_NAK:
switch (ackMessage->getResponseCode()) case FSCAckResponseCode::CONTROL_NAK_CONNECTED:
{ case FSCAckResponseCode::CONTROL_NAK_M_UNSUPP:
case FSCAckResponseCode::CONTROL_NAK: case FSCAckResponseCode::CONTROL_NAK_V_UNSUPP:
case FSCAckResponseCode::CONTROL_NAK_CONNECTED: case FSCAckResponseCode::CONTROL_NAK_F_UNSUPP:
case FSCAckResponseCode::CONTROL_NAK_M_UNSUPP: case FSCAckResponseCode::CONTROL_NAK_PARMS:
case FSCAckResponseCode::CONTROL_NAK_V_UNSUPP: case FSCAckResponseCode::CONTROL_NAK_BUSY:
case FSCAckResponseCode::CONTROL_NAK_F_UNSUPP: LogError(LOG_MODEM, "V.24 UDP, ACK, ackMessageId = $%02X, ackResponseCode = $%02X", ackMessage->getAckMessageId(), ackMessage->getResponseCode());
case FSCAckResponseCode::CONTROL_NAK_PARMS: break;
case FSCAckResponseCode::CONTROL_NAK_BUSY:
LogError(LOG_MODEM, "V.24 UDP, ACK, ackMessageId = $%02X, ackResponseCode = $%02X", ackMessage->getAckMessageId(), ackMessage->getResponseCode()); case FSCAckResponseCode::CONTROL_ACK:
break; {
if (ackMessage->getAckMessageId() == FSCMessageType::FSC_DISCONNECT) {
case FSCAckResponseCode::CONTROL_ACK: network->m_reqConnectionTimer.stop();
{ network->m_reqConnectionToPeer = true;
if (ackMessage->getAckMessageId() == FSCMessageType::FSC_DISCONNECT) { network->m_establishedConnection = false;
network->m_reqConnectionTimer.stop(); network->m_heartbeatTimer.stop();
network->m_reqConnectionToPeer = false; network->m_timeoutTimer.stop();
network->m_establishedConnection = false;
network->m_heartbeatTimer.stop();
}
} }
break; }
break;
default: default:
LogError(LOG_MODEM, "V.24 UDP, unknown ACK opcode, ackMessageId = $%02X", ackMessage->getAckMessageId()); LogError(LOG_MODEM, "V.24 UDP, unknown ACK opcode, ackMessageId = $%02X", ackMessage->getAckMessageId());
break; break;
} }
}
break;
case FSCMessageType::FSC_CONNECT:
{
if (network->m_socket != nullptr) {
network->m_socket->close();
delete network->m_socket;
} }
break;
case FSCMessageType::FSC_CONNECT: network->createVCPort(network->m_localPort);
{
network->createVCPort(network->m_localPort);
network->m_heartbeatTimer.start();
uint8_t buffer[FSCConnectResponse::LENGTH]; network->m_reqConnectionToPeer = false;
::memset(buffer, 0x00U, FSCConnectResponse::LENGTH); network->m_reqConnectionTimer.stop();
network->m_establishedConnection = true;
network->m_heartbeatTimer.start();
network->m_timeoutTimer.start();
FSCConnectResponse resp = FSCConnectResponse(req->buffer); LogMessage(LOG_MODEM, "Incoming DFSI FSC Connection, vcBasePort = %u", network->m_localPort);
resp.setVCBasePort(network->m_localPort);
resp.encode(buffer);
network->m_ctrlFrameQueue->write(buffer, FSCConnectResponse::LENGTH, network->m_controlAddr, network->m_ctrlAddrLen); uint8_t buffer[FSCConnectResponse::LENGTH];
} ::memset(buffer, 0x00U, FSCConnectResponse::LENGTH);
break;
case FSCMessageType::FSC_DISCONNECT: FSCConnectResponse resp = FSCConnectResponse();
{ resp.setVCBasePort(network->m_localPort);
network->m_reqConnectionTimer.stop(); resp.encode(buffer);
network->m_reqConnectionToPeer = false;
network->m_establishedConnection = false;
network->m_heartbeatTimer.stop();
}
break;
case FSCMessageType::FSC_HEARTBEAT: network->m_ctrlFrameQueue->write(buffer, FSCConnectResponse::LENGTH, network->m_controlAddr, network->m_ctrlAddrLen);
{ }
if (network->m_establishedConnection) { break;
network->writeHeartbeat();
} case FSCMessageType::FSC_DISCONNECT:
} {
break; LogMessage(LOG_MODEM, "DFSI FSC Disconnect");
network->m_reqConnectionTimer.stop();
network->m_reqConnectionToPeer = true;
network->m_establishedConnection = false;
network->m_heartbeatTimer.stop();
network->m_timeoutTimer.stop();
}
break;
default: case FSCMessageType::FSC_HEARTBEAT:
break; network->m_timeoutTimer.start();
} break;
default:
break;
} }
} }
} }
@ -536,6 +560,8 @@ void V24UDPPort::createVCPort(uint16_t port)
void V24UDPPort::writeConnect() void V24UDPPort::writeConnect()
{ {
LogMessage(LOG_MODEM, "Attempting DFSI FSC Connection, peerId = %u, vcBasePort = %u", m_peerId, m_localPort);
FSCConnect connect = FSCConnect(); FSCConnect connect = FSCConnect();
connect.setFSHeartbeatPeriod(5U); // hardcoded? connect.setFSHeartbeatPeriod(5U); // hardcoded?
connect.setHostHeartbeatPeriod(5U); // hardcoded? connect.setHostHeartbeatPeriod(5U); // hardcoded?

@ -72,9 +72,10 @@ namespace modem
* @param modemPort Port number. * @param modemPort Port number.
* @param controlPort Control Port number. * @param controlPort Control Port number.
* @param useFSC Flag indicating whether or not FSC handshakes are used to setup communications. * @param useFSC Flag indicating whether or not FSC handshakes are used to setup communications.
* @param fscInitiator Flag indicating whether or not the FSC handshake should be initiated when the port is opened.
* @param debug Flag indicating whether network debug is enabled. * @param debug Flag indicating whether network debug is enabled.
*/ */
V24UDPPort(uint32_t peerId, const std::string& modemAddress, uint16_t modemPort, uint16_t controlPort = 0U, bool useFSC = false, bool debug = false); V24UDPPort(uint32_t peerId, const std::string& modemAddress, uint16_t modemPort, uint16_t controlPort = 0U, bool useFSC = false, bool fscInitiator = false, bool debug = false);
/** /**
* @brief Finalizes a instance of the V24UDPPort class. * @brief Finalizes a instance of the V24UDPPort class.
*/ */
@ -132,6 +133,10 @@ namespace modem
RingBuffer<uint8_t> m_buffer; RingBuffer<uint8_t> m_buffer;
bool m_fscInitiator;
Timer m_timeoutTimer;
Timer m_reqConnectionTimer; Timer m_reqConnectionTimer;
Timer m_heartbeatTimer; Timer m_heartbeatTimer;

Loading…
Cancel
Save

Powered by TurnKey Linux.