From 8d9cfb0f46341851c53d9947f5cf363ee758d565 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 13 Aug 2017 10:30:02 +0100 Subject: [PATCH] Add YSF DSQ support. --- Conf.cpp | 17 ++++++++++++++++- Conf.h | 16 ++++++++++------ MMDVM.ini | 1 + MMDVMHost.cpp | 6 ++++++ YSFControl.cpp | 50 ++++++++++++++++++++++++++++++++++++++++---------- YSFControl.h | 4 ++++ YSFFICH.cpp | 24 ++++++++++++++++++++++++ YSFFICH.h | 4 ++++ 8 files changed, 105 insertions(+), 17 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 075a392..1327162 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -122,6 +122,8 @@ m_dmrTXHang(4U), m_fusionEnabled(false), m_fusionLowDeviation(false), m_fusionRemoteGateway(false), +m_fusionSQLEnabled(false), +m_fusionSQL(0U), m_p25Enabled(false), m_p25NAC(0x293U), m_dstarNetworkEnabled(false), @@ -451,7 +453,10 @@ bool CConf::read() m_fusionEnabled = ::atoi(value) == 1; else if (::strcmp(key, "LowDeviation") == 0) m_fusionLowDeviation = ::atoi(value) == 1; - else if (::strcmp(key, "RemoteGateway") == 0) + else if (::strcmp(key, "DSQ") == 0) { + m_fusionSQLEnabled = true; + m_fusionSQL = (unsigned int)::atoi(value); + } else if (::strcmp(key, "RemoteGateway") == 0) m_fusionRemoteGateway = ::atoi(value) == 1; } else if (section == SECTION_P25) { if (::strcmp(key, "Enable") == 0) @@ -927,6 +932,16 @@ bool CConf::getFusionRemoteGateway() const return m_fusionRemoteGateway; } +bool CConf::getFusionSQLEnabled() const +{ + return m_fusionSQLEnabled; +} + +unsigned char CConf::getFusionSQL() const +{ + return m_fusionSQL; +} + bool CConf::getP25Enabled() const { return m_p25Enabled; diff --git a/Conf.h b/Conf.h index 8845b52..d47f5dd 100644 --- a/Conf.h +++ b/Conf.h @@ -114,9 +114,11 @@ public: unsigned int getDMRTXHang() const; // The System Fusion section - bool getFusionEnabled() const; - bool getFusionLowDeviation() const; - bool getFusionRemoteGateway() const; + bool getFusionEnabled() const; + bool getFusionLowDeviation() const; + bool getFusionRemoteGateway() const; + bool getFusionSQLEnabled() const; + unsigned char getFusionSQL() const; // The P25 section bool getP25Enabled() const; @@ -269,9 +271,11 @@ private: unsigned int m_dmrCallHang; unsigned int m_dmrTXHang; - bool m_fusionEnabled; - bool m_fusionLowDeviation; - bool m_fusionRemoteGateway; + bool m_fusionEnabled; + bool m_fusionLowDeviation; + bool m_fusionRemoteGateway; + bool m_fusionSQLEnabled; + unsigned char m_fusionSQL; bool m_p25Enabled; unsigned int m_p25NAC; diff --git a/MMDVM.ini b/MMDVM.ini index 3ab581d..6451ebd 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -86,6 +86,7 @@ TXHang=4 [System Fusion] Enable=1 LowDeviation=0 +#DSQ=1 RemoteGateway=0 [P25] diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index f1c4c45..14a96e4 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -408,12 +408,18 @@ int CMMDVMHost::run() if (m_ysfEnabled) { bool lowDeviation = m_conf.getFusionLowDeviation(); bool remoteGateway = m_conf.getFusionRemoteGateway(); + bool sqlEnabled = m_conf.getFusionSQLEnabled(); + unsigned char sql = m_conf.getFusionSQL(); LogInfo("YSF Parameters"); LogInfo(" Low Deviation: %s", lowDeviation ? "yes" : "no"); LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no"); + LogInfo(" DSQ: %s", sqlEnabled ? "yes" : "no"); + if (sqlEnabled) + LogInfo(" DSQ Value: %u", sql); ysf = new CYSFControl(m_callsign, m_ysfNetwork, m_display, m_timeout, m_duplex, lowDeviation, remoteGateway, rssi); + ysf->setSQL(sqlEnabled, sql); } CP25Control* p25 = NULL; diff --git a/YSFControl.cpp b/YSFControl.cpp index 5c999a3..25db47e 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -31,6 +31,8 @@ m_display(display), m_duplex(duplex), m_lowDeviation(lowDeviation), m_remoteGateway(remoteGateway), +m_sqlEnabled(false), +m_sqlValue(0U), m_queue(5000U, "YSF Control"), m_rfState(RS_RF_LISTENING), m_netState(RS_NET_IDLE), @@ -95,6 +97,12 @@ CYSFControl::~CYSFControl() delete[] m_callsign; } +void CYSFControl::setSQL(bool on, unsigned char value) +{ + m_sqlEnabled = on; + m_sqlValue = value; +} + bool CYSFControl::writeModem(unsigned char *data, unsigned int len) { assert(data != NULL); @@ -143,6 +151,14 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) if (fi == YSF_FI_TERMINATOR) return false; + if (m_sqlEnabled) { + bool sql = fich.getSQL(); + unsigned char value = fich.getSQ(); + + if (!sql || value != m_sqlValue) + return false; + } + m_rfFrames = 0U; m_rfErrs = 0U; m_rfBits = 1U; @@ -207,6 +223,11 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) LogMessage("YSF, received RF header from ?????????? to ??????????"); } + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -233,6 +254,11 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) m_rfPayload.processHeaderData(data + 2U); + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + data[0U] = TAG_EOT; data[1U] = 0x00U; @@ -347,6 +373,11 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) } } + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -515,8 +546,6 @@ void CYSFControl::writeNetwork() data[33U] = end ? TAG_EOT : TAG_DATA; data[34U] = 0x00U; - // bool send = true; - CYSFFICH fich; bool valid = fich.decode(data + 35U); if (valid) { @@ -525,6 +554,10 @@ void CYSFControl::writeNetwork() unsigned char ft = fich.getFT(); unsigned char fi = fich.getFI(); + // Add any DSQ information + fich.setSQL(m_sqlEnabled); + fich.setSQ(m_sqlValue); + fich.setVoIP(true); fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); fich.setDev(m_lowDeviation); @@ -587,16 +620,13 @@ void CYSFControl::writeNetwork() default: break; } - } else { - // send = insertSilence(data + 33U, n); } - // if (send) { - writeQueueNet(data + 33U); - m_packetTimer.start(); - m_netFrames++; - m_netN = n; - // } + writeQueueNet(data + 33U); + + m_packetTimer.start(); + m_netFrames++; + m_netN = n; if (end) { LogMessage("YSF, received network end of transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_netFrames) / 10.0F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits)); diff --git a/YSFControl.h b/YSFControl.h index 8d2abc1..ae61902 100644 --- a/YSFControl.h +++ b/YSFControl.h @@ -37,6 +37,8 @@ public: CYSFControl(const std::string& callsign, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool lowDeviation, bool remoteGateway, CRSSIInterpolator* rssiMapper); ~CYSFControl(); + void setSQL(bool on, unsigned char value); + bool writeModem(unsigned char* data, unsigned int len); unsigned int readModem(unsigned char* data); @@ -50,6 +52,8 @@ private: bool m_duplex; bool m_lowDeviation; bool m_remoteGateway; + bool m_sqlEnabled; + unsigned char m_sqlValue; CRingBuffer m_queue; RPT_RF_STATE m_rfState; RPT_NET_STATE m_netState; diff --git a/YSFFICH.cpp b/YSFFICH.cpp index ae4fcce..e688016 100644 --- a/YSFFICH.cpp +++ b/YSFFICH.cpp @@ -204,6 +204,16 @@ bool CYSFFICH::getDev() const return (m_fich[2U] & 0x40U) == 0x40U; } +bool CYSFFICH::getSQL() const +{ + return (m_fich[3U] & 0x80U) == 0x80U; +} + +unsigned char CYSFFICH::getSQ() const +{ + return m_fich[3U] & 0x7FU; +} + void CYSFFICH::setMR(unsigned char mr) { m_fich[2U] &= 0xC7U; @@ -225,3 +235,17 @@ void CYSFFICH::setDev(bool on) else m_fich[2U] &= 0xBFU; } + +void CYSFFICH::setSQL(bool on) +{ + if (on) + m_fich[3U] |= 0x80U; + else + m_fich[3U] &= 0x7FU; +} + +void CYSFFICH::setSQ(unsigned char sq) +{ + m_fich[3U] &= 0x80U; + m_fich[3U] |= sq & 0x7FU; +} diff --git a/YSFFICH.h b/YSFFICH.h index 3837604..5b0a613 100644 --- a/YSFFICH.h +++ b/YSFFICH.h @@ -37,10 +37,14 @@ public: unsigned char getDT() const; unsigned char getMR() const; bool getDev() const; + bool getSQL() const; + unsigned char getSQ() const; void setMR(unsigned char mr); void setVoIP(bool set); void setDev(bool set); + void setSQL(bool set); + void setSQ(unsigned char sq); private: unsigned char* m_fich;