diff --git a/Conf.cpp b/Conf.cpp index 93c3234..b176709 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -106,6 +106,7 @@ m_dstarBlackList(), m_dstarAckReply(true), m_dstarAckTime(750U), m_dstarErrorReply(true), +m_dstarRemoteGateway(false), m_dstarModeHang(10U), m_dmrEnabled(false), m_dmrBeacons(false), @@ -134,6 +135,7 @@ m_p25Id(0U), m_p25NAC(0x293U), m_p25SelfOnly(false), m_p25OverrideUID(false), +m_p25RemoteGateway(false), m_p25ModeHang(10U), m_dstarNetworkEnabled(false), m_dstarGatewayAddress(), @@ -409,6 +411,8 @@ bool CConf::read() m_dstarAckTime = (unsigned int)::atoi(value); else if (::strcmp(key, "ErrorReply") == 0) m_dstarErrorReply = ::atoi(value) == 1; + else if (::strcmp(key, "RemoteGateway") == 0) + m_dstarRemoteGateway = ::atoi(value) == 1; else if (::strcmp(key, "ModeHang") == 0) m_dstarModeHang = (unsigned int)::atoi(value); } else if (section == SECTION_DMR) { @@ -497,6 +501,8 @@ bool CConf::read() m_p25OverrideUID = ::atoi(value) == 1; else if (::strcmp(key, "SelfOnly") == 0) m_p25SelfOnly = ::atoi(value) == 1; + else if (::strcmp(key, "RemoteGateway") == 0) + m_p25RemoteGateway = ::atoi(value) == 1; else if (::strcmp(key, "ModeHang") == 0) m_p25ModeHang = (unsigned int)::atoi(value); } else if (section == SECTION_DSTAR_NETWORK) { @@ -896,6 +902,11 @@ bool CConf::getDStarErrorReply() const return m_dstarErrorReply; } +bool CConf::getDStarRemoteGateway() const +{ + return m_dstarRemoteGateway; +} + unsigned int CConf::getDStarModeHang() const { return m_dstarModeHang; @@ -1036,6 +1047,11 @@ bool CConf::getP25SelfOnly() const return m_p25SelfOnly; } +bool CConf::getP25RemoteGateway() const +{ + return m_p25RemoteGateway; +} + unsigned int CConf::getP25ModeHang() const { return m_p25ModeHang; diff --git a/Conf.h b/Conf.h index 0b62ec5..fe9539a 100644 --- a/Conf.h +++ b/Conf.h @@ -97,6 +97,7 @@ public: bool getDStarAckReply() const; unsigned int getDStarAckTime() const; bool getDStarErrorReply() const; + bool getDStarRemoteGateway() const; unsigned int getDStarModeHang() const; // The DMR section @@ -131,6 +132,7 @@ public: unsigned int getP25NAC() const; bool getP25SelfOnly() const; bool getP25OverrideUID() const; + bool getP25RemoteGateway() const; unsigned int getP25ModeHang() const; // The D-Star Network section @@ -269,6 +271,7 @@ private: bool m_dstarAckReply; unsigned int m_dstarAckTime; bool m_dstarErrorReply; + bool m_dstarRemoteGateway; unsigned int m_dstarModeHang; bool m_dmrEnabled; @@ -300,6 +303,7 @@ private: unsigned int m_p25NAC; bool m_p25SelfOnly; bool m_p25OverrideUID; + bool m_p25RemoteGateway; unsigned int m_p25ModeHang; bool m_dstarNetworkEnabled; diff --git a/DStarControl.cpp b/DStarControl.cpp index b36608e..1dbf238 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -36,12 +36,13 @@ bool CallsignCompare(const std::string& arg, const unsigned char* my) // #define DUMP_DSTAR -CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool errorReply, const std::vector& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) : +CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool errorReply, const std::vector& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper) : m_callsign(NULL), m_gateway(NULL), m_selfOnly(selfOnly), m_ackReply(ackReply), m_errorReply(errorReply), +m_remoteGateway(remoteGateway), m_blackList(blackList), m_network(network), m_display(display), @@ -589,7 +590,6 @@ void CDStarControl::writeNetwork() m_netTimeoutTimer.start(); m_packetTimer.start(); - //m_elapsed.start(); // commented out and placed lower down due to delay introduced somewhere below here. m_ackTimer.stop(); m_errTimer.stop(); @@ -603,6 +603,13 @@ void CDStarControl::writeNetwork() m_netBits = 1U; m_netErrs = 0U; + if (m_remoteGateway) { + header.setRepeater(true); + header.setRPTCall1(m_callsign); + header.setRPTCall2(m_callsign); + header.get(data + 1U); + } + writeQueueHeaderNet(data); #if defined(DUMP_DSTAR) diff --git a/DStarControl.h b/DStarControl.h index 6f93336..b47f438 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -37,7 +37,7 @@ class CDStarControl { public: - CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool errorReply, const std::vector& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper); + CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool errorReply, const std::vector& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper); ~CDStarControl(); bool writeModem(unsigned char* data, unsigned int len); @@ -52,6 +52,7 @@ private: bool m_selfOnly; bool m_ackReply; bool m_errorReply; + bool m_remoteGateway; std::vector m_blackList; CDStarNetwork* m_network; CDisplay* m_display; diff --git a/MMDVM.ini b/MMDVM.ini index 741901d..1e2596c 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -71,6 +71,7 @@ SelfOnly=0 AckReply=1 AckTime=750 ErrorReply=1 +RemoteGateway=0 # ModeHang=10 [DMR] @@ -100,6 +101,7 @@ Enable=1 NAC=293 SelfOnly=0 OverrideUIDCheck=0 +RemoteGateway=0 # ModeHang=10 [D-Star Network] diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 75377c0..b968aeb 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -348,6 +348,7 @@ int CMMDVMHost::run() bool ackReply = m_conf.getDStarAckReply(); unsigned int ackTime = m_conf.getDStarAckTime(); bool errorReply = m_conf.getDStarErrorReply(); + bool remoteGateway = m_conf.getDStarRemoteGateway(); m_dstarRFModeHang = m_conf.getDStarModeHang(); LogInfo("D-Star RF Parameters"); @@ -356,12 +357,13 @@ int CMMDVMHost::run() LogInfo(" Ack Reply: %s", ackReply ? "yes" : "no"); LogInfo(" Ack Time: %ums", ackTime); LogInfo(" Error Reply: %s", errorReply ? "yes" : "no"); + LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no"); LogInfo(" Mode Hang: %us", m_dstarRFModeHang); if (blackList.size() > 0U) LogInfo(" Black List: %u", blackList.size()); - dstar = new CDStarControl(m_callsign, module, selfOnly, ackReply, ackTime, errorReply, blackList, m_dstarNetwork, m_display, m_timeout, m_duplex, rssi); + dstar = new CDStarControl(m_callsign, module, selfOnly, ackReply, ackTime, errorReply, blackList, m_dstarNetwork, m_display, m_timeout, m_duplex, remoteGateway, rssi); } CDMRControl* dmr = NULL; @@ -442,20 +444,22 @@ int CMMDVMHost::run() CP25Control* p25 = NULL; if (m_p25Enabled) { - unsigned int id = m_conf.getP25Id(); - unsigned int nac = m_conf.getP25NAC(); - bool uidOverride = m_conf.getP25OverrideUID(); - bool selfOnly = m_conf.getP25SelfOnly(); - m_p25RFModeHang = m_conf.getP25ModeHang(); + unsigned int id = m_conf.getP25Id(); + unsigned int nac = m_conf.getP25NAC(); + bool uidOverride = m_conf.getP25OverrideUID(); + bool selfOnly = m_conf.getP25SelfOnly(); + bool remoteGateway = m_conf.getP25RemoteGateway(); + m_p25RFModeHang = m_conf.getP25ModeHang(); LogInfo("P25 RF Parameters"); LogInfo(" Id: %u", id); LogInfo(" NAC: $%03X", nac); LogInfo(" UID Override: %s", uidOverride ? "yes" : "no"); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); + LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no"); LogInfo(" Mode Hang: %us", m_p25RFModeHang); - p25 = new CP25Control(nac, id, selfOnly, uidOverride, m_p25Network, m_display, m_timeout, m_duplex, m_lookup, rssi); + p25 = new CP25Control(nac, id, selfOnly, uidOverride, m_p25Network, m_display, m_timeout, m_duplex, m_lookup, remoteGateway, rssi); } setMode(MODE_IDLE); diff --git a/P25Control.cpp b/P25Control.cpp index 70707bc..d890ddd 100644 --- a/P25Control.cpp +++ b/P25Control.cpp @@ -35,11 +35,12 @@ const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U #define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) -CP25Control::CP25Control(unsigned int nac, unsigned int id, bool selfOnly, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper) : +CP25Control::CP25Control(unsigned int nac, unsigned int id, bool selfOnly, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, bool remoteGateway, CRSSIInterpolator* rssiMapper) : m_nac(nac), m_id(id), m_selfOnly(selfOnly), m_uidOverride(uidOverride), +m_remoteGateway(remoteGateway), m_network(network), m_display(display), m_duplex(duplex), @@ -752,7 +753,10 @@ void CP25Control::createNetHeader() m_netData.encodeHeader(buffer + 2U); // Add busy bits - addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, false, true); + if (m_remoteGateway) + addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, true, false); + else + addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, false, true); writeQueueNet(buffer, P25_HDR_FRAME_LENGTH_BYTES + 2U); } @@ -793,7 +797,10 @@ void CP25Control::createNetLDU1() m_netLSD.encode(buffer + 2U); // Add busy bits - addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true); + if (m_remoteGateway) + addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false); + else + addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true); writeQueueNet(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U); @@ -838,7 +845,10 @@ void CP25Control::createNetLDU2() m_netLSD.encode(buffer + 2U); // Add busy bits - addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true); + if (m_remoteGateway) + addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false); + else + addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true); writeQueueNet(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U); @@ -862,7 +872,10 @@ void CP25Control::createNetTerminator() m_nid.encode(buffer + 2U, P25_DUID_TERM); // Add busy bits - addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, false, true); + if (m_remoteGateway) + addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, true, false); + else + addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, false, true); writeQueueNet(buffer, P25_TERM_FRAME_LENGTH_BYTES + 2U); diff --git a/P25Control.h b/P25Control.h index 59dc2d3..cd0ca7c 100644 --- a/P25Control.h +++ b/P25Control.h @@ -36,7 +36,7 @@ class CP25Control { public: - CP25Control(unsigned int nac, unsigned int id, bool selfOly, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper); + CP25Control(unsigned int nac, unsigned int id, bool selfOly, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, bool remoteGateway, CRSSIInterpolator* rssiMapper); ~CP25Control(); bool writeModem(unsigned char* data, unsigned int len); @@ -50,6 +50,7 @@ private: unsigned int m_id; bool m_selfOnly; bool m_uidOverride; + bool m_remoteGateway; CP25Network* m_network; CDisplay* m_display; bool m_duplex;