From 9408367a0fb23b33ae72501516b905c9a231591e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 26 Sep 2016 18:07:06 +0100 Subject: [PATCH] Allow for remote System Fusion gateway operation. --- Conf.cpp | 8 ++++++++ Conf.h | 2 ++ MMDVM.ini | 1 + MMDVMHost.cpp | 4 +++- YSFControl.cpp | 24 +++++++++++++++++++----- YSFControl.h | 4 +++- YSFFICH.cpp | 5 +++++ YSFFICH.h | 1 + 8 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index eb9fa4d..0e034a0 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -110,6 +110,7 @@ m_dmrLookupFile(), m_dmrCallHang(3U), m_dmrTXHang(4U), m_fusionEnabled(true), +m_fusionRemoteGateway(false), m_p25Enabled(true), m_p25NAC(0x293U), m_dstarNetworkEnabled(true), @@ -435,6 +436,8 @@ bool CConf::read() } else if (section == SECTION_FUSION) { if (::strcmp(key, "Enable") == 0) m_fusionEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "RemoteGateway") == 0) + m_fusionRemoteGateway = ::atoi(value) == 1; } else if (section == SECTION_P25) { if (::strcmp(key, "Enable") == 0) m_p25Enabled = ::atoi(value) == 1; @@ -844,6 +847,11 @@ bool CConf::getFusionEnabled() const return m_fusionEnabled; } +bool CConf::getFusionRemoteGateway() const +{ + return m_fusionRemoteGateway; +} + bool CConf::getP25Enabled() const { return m_p25Enabled; diff --git a/Conf.h b/Conf.h index 9b985df..dd5c796 100644 --- a/Conf.h +++ b/Conf.h @@ -105,6 +105,7 @@ public: // The System Fusion section bool getFusionEnabled() const; + bool getFusionRemoteGateway() const; // The P25 section bool getP25Enabled() const; @@ -241,6 +242,7 @@ private: unsigned int m_dmrTXHang; bool m_fusionEnabled; + bool m_fusionRemoteGateway; bool m_p25Enabled; unsigned int m_p25NAC; diff --git a/MMDVM.ini b/MMDVM.ini index d2d959c..e272002 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -76,6 +76,7 @@ TXHang=4 [System Fusion] Enable=1 +RemoteGateway=0 [P25] Enable=1 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 47db022..69daf68 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -380,17 +380,19 @@ int CMMDVMHost::run() CYSFControl* ysf = NULL; if (m_ysfEnabled) { + bool remoteGateway = m_conf.getFusionRemoteGateway(); int rssiMultiplier = m_conf.getModemRSSIMultiplier(); int rssiOffset = m_conf.getModemRSSIOffset(); LogInfo("YSF Parameters"); + LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no"); if (rssiMultiplier != 0) { LogInfo(" RSSI Multiplier: %d", rssiMultiplier); LogInfo(" RSSI Offset: %d", rssiOffset); } - ysf = new CYSFControl(m_callsign, m_ysfNetwork, m_display, m_timeout, m_duplex, rssiMultiplier, rssiOffset); + ysf = new CYSFControl(m_callsign, m_ysfNetwork, m_display, m_timeout, m_duplex, remoteGateway, rssiMultiplier, rssiOffset); } CP25Control* p25 = NULL; diff --git a/YSFControl.cpp b/YSFControl.cpp index 3b20d1d..9ad0fb1 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -24,10 +24,11 @@ // #define DUMP_YSF -CYSFControl::CYSFControl(const std::string& callsign, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, int rssiMultiplier, int rssiOffset) : +CYSFControl::CYSFControl(const std::string& callsign, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, int rssiMultiplier, int rssiOffset) : m_network(network), m_display(display), m_duplex(duplex), +m_remoteGateway(remoteGateway), m_queue(5000U, "YSF Control"), m_rfState(RS_RF_LISTENING), m_netState(RS_NET_IDLE), @@ -50,6 +51,7 @@ m_netDest(NULL), m_lastFrame(NULL), m_lastFrameValid(false), m_lastMode(YSF_DT_VOICE_FR_MODE), +m_lastMR(YSF_MR_NOT_BUSY), m_netN(0U), m_rfPayload(), m_netPayload(), @@ -124,6 +126,18 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) if (m_rfState != RS_RF_AUDIO) return false; + if (valid) + m_lastMR = fich.getMR(); + + // Stop repeater packets coming through, unless we're acting as a remote gateway + if (m_remoteGateway) { + if (m_lastMR != YSF_MR_BUSY) + return false; + } else { + if (m_lastMR == YSF_MR_BUSY) + return false; + } + unsigned char fi = fich.getFI(); if (valid && fi == YSF_FI_HEADER) { CSync::addYSFSync(data + 2U); @@ -167,7 +181,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) #endif if (m_duplex) { - fich.setMR(YSF_MR_BUSY); + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); fich.encode(data + 2U); writeQueueRF(data); } @@ -190,7 +204,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) #endif if (m_duplex) { - fich.setMR(YSF_MR_BUSY); + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); fich.encode(data + 2U); writeQueueRF(data); } @@ -292,7 +306,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) writeNetwork(data, m_rfFrames % 128U); if (m_duplex) { - fich.setMR(YSF_MR_BUSY); + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); fich.encode(data + 2U); writeQueueRF(data); } @@ -462,7 +476,7 @@ void CYSFControl::writeNetwork() unsigned char fi = fich.getFI(); fich.setVoIP(true); - fich.setMR(YSF_MR_BUSY); + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); fich.encode(data + 35U); m_lastMode = dt; diff --git a/YSFControl.h b/YSFControl.h index 09caa62..c404cec 100644 --- a/YSFControl.h +++ b/YSFControl.h @@ -33,7 +33,7 @@ class CYSFControl { public: - CYSFControl(const std::string& callsign, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, int rssiMultiplier, int rssiOffset); + CYSFControl(const std::string& callsign, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, int rssiMultiplier, int rssiOffset); ~CYSFControl(); bool writeModem(unsigned char* data, unsigned int len); @@ -46,6 +46,7 @@ private: CYSFNetwork* m_network; CDisplay* m_display; bool m_duplex; + bool m_remoteGateway; CRingBuffer m_queue; RPT_RF_STATE m_rfState; RPT_NET_STATE m_netState; @@ -68,6 +69,7 @@ private: unsigned char* m_lastFrame; bool m_lastFrameValid; unsigned char m_lastMode; + unsigned char m_lastMR; unsigned char m_netN; CYSFPayload m_rfPayload; CYSFPayload m_netPayload; diff --git a/YSFFICH.cpp b/YSFFICH.cpp index a8b1ae1..4ed9169 100644 --- a/YSFFICH.cpp +++ b/YSFFICH.cpp @@ -194,6 +194,11 @@ unsigned char CYSFFICH::getDT() const return m_fich[2U] & 0x03U; } +unsigned char CYSFFICH::getMR() const +{ + return (m_fich[2U] >> 3) & 0x03U; +} + void CYSFFICH::setMR(unsigned char mr) { m_fich[2U] &= 0xC7U; diff --git a/YSFFICH.h b/YSFFICH.h index 534e6f6..8b8d0bd 100644 --- a/YSFFICH.h +++ b/YSFFICH.h @@ -35,6 +35,7 @@ public: unsigned char getFN() const; unsigned char getFT() const; unsigned char getDT() const; + unsigned char getMR() const; void setMR(unsigned char mr); void setVoIP(bool set);