Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions configs/bridge-config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,5 @@ system:
rtsPttEnable: false
# Serial port device for RTS PTT control (e.g., /dev/ttyUSB0).
rtsPttPort: "/dev/ttyUSB0"
# Hold-off time (ms) before clearing RTS PTT after last audio output.
rtsPttHoldoffMs: 250
27 changes: 22 additions & 5 deletions src/bridge/HostBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*
* Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL
* Copyright (C) 2025 Caleb, K4PHP
* Copyright (C) 2025 Lorenzo L Romero, K2LLR
*
*/
#include "Defines.h"
Expand Down Expand Up @@ -114,12 +115,9 @@ void audioCallback(ma_device* device, void* output, const void* input, ma_uint32
pcmIdx += 2;
}

// Assert RTS PTT when audio is being sent to output
// Assert RTS PTT when audio is being sent to output and record last output time
bridge->assertRtsPtt();
}
else {
// Deassert RTS PTT when no audio is being sent to output
bridge->deassertRtsPtt();
bridge->m_lastAudioOut = system_clock::hrc::now();
}
}

Expand Down Expand Up @@ -285,6 +283,10 @@ HostBridge::HostBridge(const std::string& confFile) :
::memset(m_netLDU2, 0x00U, 9U * 25U);

m_p25Crypto = new p25::crypto::P25Crypto();

// initialize RTS PTT timing
m_lastAudioOut = system_clock::hrc::now();
m_rtsPttHoldoffMs = 250U;
}

/* Finalizes a instance of the HostBridge class. */
Expand Down Expand Up @@ -946,6 +948,7 @@ bool HostBridge::readParams()
// RTS PTT Configuration
m_rtsPttEnable = systemConf["rtsPttEnable"].as<bool>(false);
m_rtsPttPort = systemConf["rtsPttPort"].as<std::string>("/dev/ttyUSB0");
m_rtsPttHoldoffMs = (uint32_t)systemConf["rtsPttHoldoffMs"].as<uint32_t>(m_rtsPttHoldoffMs);

std::string txModeStr = "DMR";
if (m_txMode == TX_MODE_P25)
Expand Down Expand Up @@ -975,6 +978,7 @@ bool HostBridge::readParams()
LogInfo(" RTS PTT Enable: %s", m_rtsPttEnable ? "yes" : "no");
if (m_rtsPttEnable) {
LogInfo(" RTS PTT Port: %s", m_rtsPttPort.c_str());
LogInfo(" RTS PTT Hold-off: %ums", m_rtsPttHoldoffMs);
}

if (m_debug) {
Expand Down Expand Up @@ -2970,6 +2974,11 @@ void HostBridge::callEnd(uint32_t srcId, uint32_t dstId)
m_trafficFromUDP = false;
m_udpFrameCnt = 0U;

// ensure PTT is dropped at call end
if (m_rtsPttEnable) {
deassertRtsPtt();
}

m_dmrSeqNo = 0U;
m_dmrN = 0U;
m_p25SeqNo = 0U;
Expand Down Expand Up @@ -3758,6 +3767,14 @@ void* HostBridge::threadCallWatchdog(void* arg)
bridge->m_udpDropTime.clock(ms);
}

// Debounce RTS PTT clear using hold-off after last audio output
if (bridge->m_rtsPttEnable && bridge->m_rtsPttActive) {
uint64_t sinceLastOut = system_clock::hrc::diffNow(bridge->m_lastAudioOut);
if (sinceLastOut >= bridge->m_rtsPttHoldoffMs) {
bridge->deassertRtsPtt();
}
}

std::string trafficType = LOCAL_CALL;
if (bridge->m_trafficFromUDP)
trafficType = UDP_CALL;
Expand Down
4 changes: 4 additions & 0 deletions src/bridge/HostBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "common/yaml/Yaml.h"
#include "common/RingBuffer.h"
#include "common/Timer.h"
#include "common/Clock.h"
#include "vocoder/MBEDecoder.h"
#include "vocoder/MBEEncoder.h"
#define MINIAUDIO_IMPLEMENTATION
Expand Down Expand Up @@ -260,6 +261,9 @@ class HOST_SW_API HostBridge {
std::string m_rtsPttPort;
RtsPttController* m_rtsPttController;
bool m_rtsPttActive;
// Timestamp of last audio written to output and hold-off before clearing PTT
system_clock::hrc::hrc_t m_lastAudioOut;
uint32_t m_rtsPttHoldoffMs;

uint16_t m_rtpSeqNo;
uint32_t m_rtpTimestamp;
Expand Down