Allow for remote System Fusion gateway operation.
This commit is contained in:
parent
f6a485fe6b
commit
9408367a0f
8 changed files with 42 additions and 7 deletions
8
Conf.cpp
8
Conf.cpp
|
@ -110,6 +110,7 @@ m_dmrLookupFile(),
|
||||||
m_dmrCallHang(3U),
|
m_dmrCallHang(3U),
|
||||||
m_dmrTXHang(4U),
|
m_dmrTXHang(4U),
|
||||||
m_fusionEnabled(true),
|
m_fusionEnabled(true),
|
||||||
|
m_fusionRemoteGateway(false),
|
||||||
m_p25Enabled(true),
|
m_p25Enabled(true),
|
||||||
m_p25NAC(0x293U),
|
m_p25NAC(0x293U),
|
||||||
m_dstarNetworkEnabled(true),
|
m_dstarNetworkEnabled(true),
|
||||||
|
@ -435,6 +436,8 @@ bool CConf::read()
|
||||||
} else if (section == SECTION_FUSION) {
|
} else if (section == SECTION_FUSION) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_fusionEnabled = ::atoi(value) == 1;
|
m_fusionEnabled = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "RemoteGateway") == 0)
|
||||||
|
m_fusionRemoteGateway = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_P25) {
|
} else if (section == SECTION_P25) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_p25Enabled = ::atoi(value) == 1;
|
m_p25Enabled = ::atoi(value) == 1;
|
||||||
|
@ -844,6 +847,11 @@ bool CConf::getFusionEnabled() const
|
||||||
return m_fusionEnabled;
|
return m_fusionEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CConf::getFusionRemoteGateway() const
|
||||||
|
{
|
||||||
|
return m_fusionRemoteGateway;
|
||||||
|
}
|
||||||
|
|
||||||
bool CConf::getP25Enabled() const
|
bool CConf::getP25Enabled() const
|
||||||
{
|
{
|
||||||
return m_p25Enabled;
|
return m_p25Enabled;
|
||||||
|
|
2
Conf.h
2
Conf.h
|
@ -105,6 +105,7 @@ public:
|
||||||
|
|
||||||
// The System Fusion section
|
// The System Fusion section
|
||||||
bool getFusionEnabled() const;
|
bool getFusionEnabled() const;
|
||||||
|
bool getFusionRemoteGateway() const;
|
||||||
|
|
||||||
// The P25 section
|
// The P25 section
|
||||||
bool getP25Enabled() const;
|
bool getP25Enabled() const;
|
||||||
|
@ -241,6 +242,7 @@ private:
|
||||||
unsigned int m_dmrTXHang;
|
unsigned int m_dmrTXHang;
|
||||||
|
|
||||||
bool m_fusionEnabled;
|
bool m_fusionEnabled;
|
||||||
|
bool m_fusionRemoteGateway;
|
||||||
|
|
||||||
bool m_p25Enabled;
|
bool m_p25Enabled;
|
||||||
unsigned int m_p25NAC;
|
unsigned int m_p25NAC;
|
||||||
|
|
|
@ -76,6 +76,7 @@ TXHang=4
|
||||||
|
|
||||||
[System Fusion]
|
[System Fusion]
|
||||||
Enable=1
|
Enable=1
|
||||||
|
RemoteGateway=0
|
||||||
|
|
||||||
[P25]
|
[P25]
|
||||||
Enable=1
|
Enable=1
|
||||||
|
|
|
@ -380,17 +380,19 @@ int CMMDVMHost::run()
|
||||||
|
|
||||||
CYSFControl* ysf = NULL;
|
CYSFControl* ysf = NULL;
|
||||||
if (m_ysfEnabled) {
|
if (m_ysfEnabled) {
|
||||||
|
bool remoteGateway = m_conf.getFusionRemoteGateway();
|
||||||
int rssiMultiplier = m_conf.getModemRSSIMultiplier();
|
int rssiMultiplier = m_conf.getModemRSSIMultiplier();
|
||||||
int rssiOffset = m_conf.getModemRSSIOffset();
|
int rssiOffset = m_conf.getModemRSSIOffset();
|
||||||
|
|
||||||
LogInfo("YSF Parameters");
|
LogInfo("YSF Parameters");
|
||||||
|
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");
|
||||||
|
|
||||||
if (rssiMultiplier != 0) {
|
if (rssiMultiplier != 0) {
|
||||||
LogInfo(" RSSI Multiplier: %d", rssiMultiplier);
|
LogInfo(" RSSI Multiplier: %d", rssiMultiplier);
|
||||||
LogInfo(" RSSI Offset: %d", rssiOffset);
|
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;
|
CP25Control* p25 = NULL;
|
||||||
|
|
|
@ -24,10 +24,11 @@
|
||||||
|
|
||||||
// #define DUMP_YSF
|
// #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_network(network),
|
||||||
m_display(display),
|
m_display(display),
|
||||||
m_duplex(duplex),
|
m_duplex(duplex),
|
||||||
|
m_remoteGateway(remoteGateway),
|
||||||
m_queue(5000U, "YSF Control"),
|
m_queue(5000U, "YSF Control"),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RS_RF_LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RS_NET_IDLE),
|
||||||
|
@ -50,6 +51,7 @@ m_netDest(NULL),
|
||||||
m_lastFrame(NULL),
|
m_lastFrame(NULL),
|
||||||
m_lastFrameValid(false),
|
m_lastFrameValid(false),
|
||||||
m_lastMode(YSF_DT_VOICE_FR_MODE),
|
m_lastMode(YSF_DT_VOICE_FR_MODE),
|
||||||
|
m_lastMR(YSF_MR_NOT_BUSY),
|
||||||
m_netN(0U),
|
m_netN(0U),
|
||||||
m_rfPayload(),
|
m_rfPayload(),
|
||||||
m_netPayload(),
|
m_netPayload(),
|
||||||
|
@ -124,6 +126,18 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (m_rfState != RS_RF_AUDIO)
|
if (m_rfState != RS_RF_AUDIO)
|
||||||
return false;
|
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();
|
unsigned char fi = fich.getFI();
|
||||||
if (valid && fi == YSF_FI_HEADER) {
|
if (valid && fi == YSF_FI_HEADER) {
|
||||||
CSync::addYSFSync(data + 2U);
|
CSync::addYSFSync(data + 2U);
|
||||||
|
@ -167,7 +181,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
fich.setMR(YSF_MR_BUSY);
|
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
||||||
fich.encode(data + 2U);
|
fich.encode(data + 2U);
|
||||||
writeQueueRF(data);
|
writeQueueRF(data);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +204,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
fich.setMR(YSF_MR_BUSY);
|
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
||||||
fich.encode(data + 2U);
|
fich.encode(data + 2U);
|
||||||
writeQueueRF(data);
|
writeQueueRF(data);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +306,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
writeNetwork(data, m_rfFrames % 128U);
|
writeNetwork(data, m_rfFrames % 128U);
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
fich.setMR(YSF_MR_BUSY);
|
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
||||||
fich.encode(data + 2U);
|
fich.encode(data + 2U);
|
||||||
writeQueueRF(data);
|
writeQueueRF(data);
|
||||||
}
|
}
|
||||||
|
@ -462,7 +476,7 @@ void CYSFControl::writeNetwork()
|
||||||
unsigned char fi = fich.getFI();
|
unsigned char fi = fich.getFI();
|
||||||
|
|
||||||
fich.setVoIP(true);
|
fich.setVoIP(true);
|
||||||
fich.setMR(YSF_MR_BUSY);
|
fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY);
|
||||||
fich.encode(data + 35U);
|
fich.encode(data + 35U);
|
||||||
|
|
||||||
m_lastMode = dt;
|
m_lastMode = dt;
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
class CYSFControl {
|
class CYSFControl {
|
||||||
public:
|
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();
|
~CYSFControl();
|
||||||
|
|
||||||
bool writeModem(unsigned char* data, unsigned int len);
|
bool writeModem(unsigned char* data, unsigned int len);
|
||||||
|
@ -46,6 +46,7 @@ private:
|
||||||
CYSFNetwork* m_network;
|
CYSFNetwork* m_network;
|
||||||
CDisplay* m_display;
|
CDisplay* m_display;
|
||||||
bool m_duplex;
|
bool m_duplex;
|
||||||
|
bool m_remoteGateway;
|
||||||
CRingBuffer<unsigned char> m_queue;
|
CRingBuffer<unsigned char> m_queue;
|
||||||
RPT_RF_STATE m_rfState;
|
RPT_RF_STATE m_rfState;
|
||||||
RPT_NET_STATE m_netState;
|
RPT_NET_STATE m_netState;
|
||||||
|
@ -68,6 +69,7 @@ private:
|
||||||
unsigned char* m_lastFrame;
|
unsigned char* m_lastFrame;
|
||||||
bool m_lastFrameValid;
|
bool m_lastFrameValid;
|
||||||
unsigned char m_lastMode;
|
unsigned char m_lastMode;
|
||||||
|
unsigned char m_lastMR;
|
||||||
unsigned char m_netN;
|
unsigned char m_netN;
|
||||||
CYSFPayload m_rfPayload;
|
CYSFPayload m_rfPayload;
|
||||||
CYSFPayload m_netPayload;
|
CYSFPayload m_netPayload;
|
||||||
|
|
|
@ -194,6 +194,11 @@ unsigned char CYSFFICH::getDT() const
|
||||||
return m_fich[2U] & 0x03U;
|
return m_fich[2U] & 0x03U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getMR() const
|
||||||
|
{
|
||||||
|
return (m_fich[2U] >> 3) & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
void CYSFFICH::setMR(unsigned char mr)
|
void CYSFFICH::setMR(unsigned char mr)
|
||||||
{
|
{
|
||||||
m_fich[2U] &= 0xC7U;
|
m_fich[2U] &= 0xC7U;
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
unsigned char getFN() const;
|
unsigned char getFN() const;
|
||||||
unsigned char getFT() const;
|
unsigned char getFT() const;
|
||||||
unsigned char getDT() const;
|
unsigned char getDT() const;
|
||||||
|
unsigned char getMR() const;
|
||||||
|
|
||||||
void setMR(unsigned char mr);
|
void setMR(unsigned char mr);
|
||||||
void setVoIP(bool set);
|
void setVoIP(bool set);
|
||||||
|
|
Loading…
Reference in a new issue