mirror of
https://github.com/ShaYmez/P25Clients.git
synced 2024-09-27 11:26:33 -04:00
Allow for static and dynamic TGs.
This commit is contained in:
parent
51c0d3a529
commit
adb4ab511d
@ -32,8 +32,7 @@ enum SECTION {
|
|||||||
SECTION_ID_LOOKUP,
|
SECTION_ID_LOOKUP,
|
||||||
SECTION_VOICE,
|
SECTION_VOICE,
|
||||||
SECTION_LOG,
|
SECTION_LOG,
|
||||||
SECTION_NETWORK,
|
SECTION_NETWORK
|
||||||
SECTION_REMOTE_COMMANDS
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CConf::CConf(const std::string& file) :
|
CConf::CConf(const std::string& file) :
|
||||||
@ -42,6 +41,7 @@ m_callsign(),
|
|||||||
m_rptAddress(),
|
m_rptAddress(),
|
||||||
m_rptPort(0U),
|
m_rptPort(0U),
|
||||||
m_myPort(0U),
|
m_myPort(0U),
|
||||||
|
m_debug(false),
|
||||||
m_daemon(false),
|
m_daemon(false),
|
||||||
m_lookupName(),
|
m_lookupName(),
|
||||||
m_lookupTime(0U),
|
m_lookupTime(0U),
|
||||||
@ -58,11 +58,10 @@ m_networkHosts2(),
|
|||||||
m_networkReloadTime(0U),
|
m_networkReloadTime(0U),
|
||||||
m_networkParrotAddress("127.0.0.1"),
|
m_networkParrotAddress("127.0.0.1"),
|
||||||
m_networkParrotPort(0U),
|
m_networkParrotPort(0U),
|
||||||
m_networkStartup(9999U),
|
m_networkStatic(),
|
||||||
m_networkInactivityTimeout(0U),
|
m_networkRFHangTime(120U),
|
||||||
m_networkDebug(false),
|
m_networkNetHangTime(60U),
|
||||||
m_remoteCommandsEnabled(false),
|
m_networkDebug(false)
|
||||||
m_remoteCommandsPort(6074U)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +95,6 @@ bool CConf::read()
|
|||||||
section = SECTION_LOG;
|
section = SECTION_LOG;
|
||||||
else if (::strncmp(buffer, "[Network]", 9U) == 0)
|
else if (::strncmp(buffer, "[Network]", 9U) == 0)
|
||||||
section = SECTION_NETWORK;
|
section = SECTION_NETWORK;
|
||||||
else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0)
|
|
||||||
section = SECTION_REMOTE_COMMANDS;
|
|
||||||
else
|
else
|
||||||
section = SECTION_NONE;
|
section = SECTION_NONE;
|
||||||
|
|
||||||
@ -141,6 +138,8 @@ bool CConf::read()
|
|||||||
m_rptPort = (unsigned int)::atoi(value);
|
m_rptPort = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "LocalPort") == 0)
|
else if (::strcmp(key, "LocalPort") == 0)
|
||||||
m_myPort = (unsigned int)::atoi(value);
|
m_myPort = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
|
m_debug = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Daemon") == 0)
|
else if (::strcmp(key, "Daemon") == 0)
|
||||||
m_daemon = ::atoi(value) == 1;
|
m_daemon = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_ID_LOOKUP) {
|
} else if (section == SECTION_ID_LOOKUP) {
|
||||||
@ -181,17 +180,19 @@ bool CConf::read()
|
|||||||
m_networkP252DMRAddress = value;
|
m_networkP252DMRAddress = value;
|
||||||
else if (::strcmp(key, "P252DMRPort") == 0)
|
else if (::strcmp(key, "P252DMRPort") == 0)
|
||||||
m_networkP252DMRPort = (unsigned int)::atoi(value);
|
m_networkP252DMRPort = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Startup") == 0)
|
else if (::strcmp(key, "Static") == 0) {
|
||||||
m_networkStartup = (unsigned int)::atoi(value);
|
char* p = ::strtok(value, ",\r\n");
|
||||||
else if (::strcmp(key, "InactivityTimeout") == 0)
|
while (p != NULL) {
|
||||||
m_networkInactivityTimeout = (unsigned int)::atoi(value);
|
unsigned int tg = (unsigned int)::atoi(p);
|
||||||
|
m_networkStatic.push_back(tg);
|
||||||
|
p = ::strtok(NULL, ",\r\n");
|
||||||
|
}
|
||||||
|
} else if (::strcmp(key, "RFHangTime") == 0)
|
||||||
|
m_networkRFHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "NetHangTime") == 0)
|
||||||
|
m_networkNetHangTime = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_networkDebug = ::atoi(value) == 1;
|
m_networkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_REMOTE_COMMANDS) {
|
|
||||||
if (::strcmp(key, "Enable") == 0)
|
|
||||||
m_remoteCommandsEnabled = ::atoi(value) == 1;
|
|
||||||
else if (::strcmp(key, "Port") == 0)
|
|
||||||
m_remoteCommandsPort = (unsigned int)::atoi(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +221,11 @@ unsigned int CConf::getMyPort() const
|
|||||||
return m_myPort;
|
return m_myPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CConf::getDebug() const
|
||||||
|
{
|
||||||
|
return m_debug;
|
||||||
|
}
|
||||||
|
|
||||||
bool CConf::getDaemon() const
|
bool CConf::getDaemon() const
|
||||||
{
|
{
|
||||||
return m_daemon;
|
return m_daemon;
|
||||||
@ -310,27 +316,22 @@ unsigned int CConf::getNetworkP252DMRPort() const
|
|||||||
return m_networkP252DMRPort;
|
return m_networkP252DMRPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CConf::getNetworkStartup() const
|
std::vector<unsigned int> CConf::getNetworkStatic() const
|
||||||
{
|
{
|
||||||
return m_networkStartup;
|
return m_networkStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CConf::getNetworkInactivityTimeout() const
|
unsigned int CConf::getNetworkRFHangTime() const
|
||||||
{
|
{
|
||||||
return m_networkInactivityTimeout;
|
return m_networkRFHangTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getNetworkNetHangTime() const
|
||||||
|
{
|
||||||
|
return m_networkNetHangTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CConf::getNetworkDebug() const
|
bool CConf::getNetworkDebug() const
|
||||||
{
|
{
|
||||||
return m_networkDebug;
|
return m_networkDebug;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CConf::getRemoteCommandsEnabled() const
|
|
||||||
{
|
|
||||||
return m_remoteCommandsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int CConf::getRemoteCommandsPort() const
|
|
||||||
{
|
|
||||||
return m_remoteCommandsPort;
|
|
||||||
}
|
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
std::string getRptAddress() const;
|
std::string getRptAddress() const;
|
||||||
unsigned int getRptPort() const;
|
unsigned int getRptPort() const;
|
||||||
unsigned int getMyPort() const;
|
unsigned int getMyPort() const;
|
||||||
|
bool getDebug() const;
|
||||||
bool getDaemon() const;
|
bool getDaemon() const;
|
||||||
|
|
||||||
// The Id Lookup section
|
// The Id Lookup section
|
||||||
@ -61,20 +62,18 @@ public:
|
|||||||
unsigned int getNetworkParrotPort() const;
|
unsigned int getNetworkParrotPort() const;
|
||||||
std::string getNetworkP252DMRAddress() const;
|
std::string getNetworkP252DMRAddress() const;
|
||||||
unsigned int getNetworkP252DMRPort() const;
|
unsigned int getNetworkP252DMRPort() const;
|
||||||
unsigned int getNetworkStartup() const;
|
std::vector<unsigned int> getNetworkStatic() const;
|
||||||
unsigned int getNetworkInactivityTimeout() const;
|
unsigned int getNetworkRFHangTime() const;
|
||||||
|
unsigned int getNetworkNetHangTime() const;
|
||||||
bool getNetworkDebug() const;
|
bool getNetworkDebug() const;
|
||||||
|
|
||||||
// The Remote Commands section
|
|
||||||
bool getRemoteCommandsEnabled() const;
|
|
||||||
unsigned int getRemoteCommandsPort() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_file;
|
std::string m_file;
|
||||||
std::string m_callsign;
|
std::string m_callsign;
|
||||||
std::string m_rptAddress;
|
std::string m_rptAddress;
|
||||||
unsigned int m_rptPort;
|
unsigned int m_rptPort;
|
||||||
unsigned int m_myPort;
|
unsigned int m_myPort;
|
||||||
|
bool m_debug;
|
||||||
bool m_daemon;
|
bool m_daemon;
|
||||||
|
|
||||||
std::string m_lookupName;
|
std::string m_lookupName;
|
||||||
@ -97,12 +96,10 @@ private:
|
|||||||
unsigned int m_networkParrotPort;
|
unsigned int m_networkParrotPort;
|
||||||
std::string m_networkP252DMRAddress;
|
std::string m_networkP252DMRAddress;
|
||||||
unsigned int m_networkP252DMRPort;
|
unsigned int m_networkP252DMRPort;
|
||||||
unsigned int m_networkStartup;
|
std::vector<unsigned int> m_networkStatic;;
|
||||||
unsigned int m_networkInactivityTimeout;
|
unsigned int m_networkRFHangTime;
|
||||||
|
unsigned int m_networkNetHangTime;
|
||||||
bool m_networkDebug;
|
bool m_networkDebug;
|
||||||
|
|
||||||
bool m_remoteCommandsEnabled;
|
|
||||||
unsigned int m_remoteCommandsPort;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,6 +57,13 @@ const unsigned P25_VOICE_ID = 10999U;
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
class CStaticTG {
|
||||||
|
public:
|
||||||
|
unsigned int m_tg;
|
||||||
|
sockaddr_storage m_addr;
|
||||||
|
unsigned int m_addrLen;
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
const char* iniFile = DEFAULT_INI_FILE;
|
const char* iniFile = DEFAULT_INI_FILE;
|
||||||
@ -181,17 +188,7 @@ void CP25Gateway::run()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUDPSocket* remoteSocket = NULL;
|
CNetwork localNetwork(m_conf.getMyPort(), m_conf.getCallsign(), m_conf.getDebug());
|
||||||
if (m_conf.getRemoteCommandsEnabled()) {
|
|
||||||
remoteSocket = new CUDPSocket(m_conf.getRemoteCommandsPort());
|
|
||||||
ret = remoteSocket->open();
|
|
||||||
if (!ret) {
|
|
||||||
delete remoteSocket;
|
|
||||||
remoteSocket = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CNetwork localNetwork(m_conf.getMyPort(), m_conf.getCallsign(), false);
|
|
||||||
ret = localNetwork.open();
|
ret = localNetwork.open();
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
::LogFinalise();
|
::LogFinalise();
|
||||||
@ -216,9 +213,13 @@ void CP25Gateway::run()
|
|||||||
CDMRLookup* lookup = new CDMRLookup(m_conf.getLookupName(), m_conf.getLookupTime());
|
CDMRLookup* lookup = new CDMRLookup(m_conf.getLookupName(), m_conf.getLookupTime());
|
||||||
lookup->read();
|
lookup->read();
|
||||||
|
|
||||||
CTimer inactivityTimer(1000U, m_conf.getNetworkInactivityTimeout() * 60U);
|
unsigned int rfHangTime = m_conf.getNetworkRFHangTime();
|
||||||
CTimer lostTimer(1000U, 120U);
|
unsigned int netHangTime = m_conf.getNetworkNetHangTime();
|
||||||
|
|
||||||
|
CTimer hangTimer(1000U);
|
||||||
|
|
||||||
CTimer pollTimer(1000U, 5U);
|
CTimer pollTimer(1000U, 5U);
|
||||||
|
pollTimer.start();
|
||||||
|
|
||||||
CStopWatch stopWatch;
|
CStopWatch stopWatch;
|
||||||
stopWatch.start();
|
stopWatch.start();
|
||||||
@ -236,145 +237,189 @@ void CP25Gateway::run()
|
|||||||
LogMessage("Starting P25Gateway-%s", VERSION);
|
LogMessage("Starting P25Gateway-%s", VERSION);
|
||||||
|
|
||||||
unsigned int srcId = 0U;
|
unsigned int srcId = 0U;
|
||||||
unsigned int dstId = 0U;
|
unsigned int dstTG = 0U;
|
||||||
|
|
||||||
unsigned int currentId = 9999U;
|
bool currentIsStatic = false;
|
||||||
|
unsigned int currentTG = 0U;
|
||||||
unsigned int currentAddrLen = 0U;
|
unsigned int currentAddrLen = 0U;
|
||||||
sockaddr_storage currentAddr;
|
sockaddr_storage currentAddr;
|
||||||
|
|
||||||
unsigned int startupId = m_conf.getNetworkStartup();
|
std::vector<unsigned int> staticIds = m_conf.getNetworkStatic();
|
||||||
bool p252dmr_enabled = (startupId == 20) ? true : false;
|
|
||||||
|
std::vector<CStaticTG> staticTGs;
|
||||||
if (startupId != 9999U) {
|
for (std::vector<unsigned int>::const_iterator it = staticIds.cbegin(); it != staticIds.cend(); ++it) {
|
||||||
CP25Reflector* reflector = reflectors.find(startupId);
|
CP25Reflector* reflector = reflectors.find(*it);
|
||||||
if (reflector != NULL) {
|
if (reflector != NULL) {
|
||||||
currentId = startupId;
|
CStaticTG staticTG;
|
||||||
currentAddr = reflector->m_addr;
|
staticTG.m_tg = *it;
|
||||||
currentAddrLen = reflector->m_addrLen;
|
staticTG.m_addr = reflector->m_addr;
|
||||||
|
staticTG.m_addrLen = reflector->m_addrLen;
|
||||||
|
staticTGs.push_back(staticTG);
|
||||||
|
|
||||||
inactivityTimer.start();
|
remoteNetwork.writePoll(staticTG.m_addr, staticTG.m_addrLen);
|
||||||
pollTimer.start();
|
remoteNetwork.writePoll(staticTG.m_addr, staticTG.m_addrLen);
|
||||||
lostTimer.start();
|
remoteNetwork.writePoll(staticTG.m_addr, staticTG.m_addrLen);
|
||||||
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
LogMessage("Statically linked to reflector %u", *it);
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
|
|
||||||
LogMessage("Linked at startup to reflector %u", currentId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
unsigned char buffer[200U];
|
unsigned char buffer[200U];
|
||||||
sockaddr_storage addr;
|
sockaddr_storage addr;
|
||||||
unsigned int addrlen;
|
unsigned int addrLen;
|
||||||
|
|
||||||
// From the reflector to the MMDVM
|
// From the reflector to the MMDVM
|
||||||
unsigned int len = remoteNetwork.readData(buffer, 200U, addr, addrlen);
|
unsigned int len = remoteNetwork.readData(buffer, 200U, addr, addrLen);
|
||||||
if (len > 0U) {
|
if (len > 0U) {
|
||||||
// If we're linked and it's from the right place, send it on
|
// If we're linked and it's from the right place, send it on
|
||||||
if (currentId != 9999U && CUDPSocket::match(currentAddr, addr)) {
|
if (currentTG > 0U && CUDPSocket::match(currentAddr, addr)) {
|
||||||
// Don't pass reflector control data through to the MMDVM
|
// Don't pass reflector control data through to the MMDVM
|
||||||
if (buffer[0U] != 0xF0U && buffer[0U] != 0xF1U) {
|
if (buffer[0U] != 0xF0U && buffer[0U] != 0xF1U) {
|
||||||
// Rewrite the LCF and the destination TG
|
// Rewrite the LCF and the destination TG
|
||||||
if (buffer[0U] == 0x64U) {
|
if (buffer[0U] == 0x64U) {
|
||||||
buffer[1U] = 0x00U; // LCF is for TGs
|
buffer[1U] = 0x00U; // LCF is for TGs
|
||||||
} else if (buffer[0U] == 0x65U) {
|
} else if (buffer[0U] == 0x65U) {
|
||||||
buffer[1U] = (currentId >> 16) & 0xFFU;
|
buffer[1U] = (currentTG >> 16) & 0xFFU;
|
||||||
buffer[2U] = (currentId >> 8) & 0xFFU;
|
buffer[2U] = (currentTG >> 8) & 0xFFU;
|
||||||
buffer[3U] = (currentId >> 0) & 0xFFU;
|
buffer[3U] = (currentTG >> 0) & 0xFFU;
|
||||||
}
|
}
|
||||||
|
|
||||||
localNetwork.writeData(buffer, len, rptAddr, rptAddrLen);
|
localNetwork.writeData(buffer, len, rptAddr, rptAddrLen);
|
||||||
}
|
|
||||||
|
|
||||||
// Any network activity is proof that the reflector is alive
|
hangTimer.start();
|
||||||
lostTimer.start();
|
}
|
||||||
|
} else if (currentTG == 0U) {
|
||||||
|
// Don't pass reflector control data through to the MMDVM
|
||||||
|
if (buffer[0U] != 0xF0U && buffer[0U] != 0xF1U) {
|
||||||
|
// Find the static TG that this audio data belongs to
|
||||||
|
for (std::vector<CStaticTG>::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it) {
|
||||||
|
if (CUDPSocket::match(addr, (*it).m_addr)) {
|
||||||
|
currentTG = (*it).m_tg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTG > 0U) {
|
||||||
|
currentAddr = addr;
|
||||||
|
currentAddrLen = addrLen;
|
||||||
|
currentIsStatic = true;
|
||||||
|
|
||||||
|
// Rewrite the LCF and the destination TG
|
||||||
|
if (buffer[0U] == 0x64U) {
|
||||||
|
buffer[1U] = 0x00U; // LCF is for TGs
|
||||||
|
} else if (buffer[0U] == 0x65U) {
|
||||||
|
buffer[1U] = (currentTG >> 16) & 0xFFU;
|
||||||
|
buffer[2U] = (currentTG >> 8) & 0xFFU;
|
||||||
|
buffer[3U] = (currentTG >> 0) & 0xFFU;
|
||||||
|
}
|
||||||
|
|
||||||
|
localNetwork.writeData(buffer, len, rptAddr, rptAddrLen);
|
||||||
|
|
||||||
|
LogMessage("Switched to reflector %u due to network activity", currentTG);
|
||||||
|
|
||||||
|
hangTimer.setTimeout(netHangTime);
|
||||||
|
hangTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// From the MMDVM to the reflector or control data
|
// From the MMDVM to the reflector or control data
|
||||||
len = localNetwork.readData(buffer, 200U, addr, addrlen);
|
len = localNetwork.readData(buffer, 200U, addr, addrLen);
|
||||||
if (len > 0U) {
|
if (len > 0U) {
|
||||||
if (buffer[0U] == 0x65U) {
|
if (buffer[0U] == 0x65U) {
|
||||||
dstId = (buffer[1U] << 16) & 0xFF0000U;
|
dstTG = (buffer[1U] << 16) & 0xFF0000U;
|
||||||
dstId |= (buffer[2U] << 8) & 0x00FF00U;
|
dstTG |= (buffer[2U] << 8) & 0x00FF00U;
|
||||||
dstId |= (buffer[3U] << 0) & 0x0000FFU;
|
dstTG |= (buffer[3U] << 0) & 0x0000FFU;
|
||||||
} else if (buffer[0U] == 0x66U) {
|
} else if (buffer[0U] == 0x66U) {
|
||||||
srcId = (buffer[1U] << 16) & 0xFF0000U;
|
srcId = (buffer[1U] << 16) & 0xFF0000U;
|
||||||
srcId |= (buffer[2U] << 8) & 0x00FF00U;
|
srcId |= (buffer[2U] << 8) & 0x00FF00U;
|
||||||
srcId |= (buffer[3U] << 0) & 0x0000FFU;
|
srcId |= (buffer[3U] << 0) & 0x0000FFU;
|
||||||
|
|
||||||
if(p252dmr_enabled){
|
if (dstTG != currentTG) {
|
||||||
currentId = dstId;
|
if (currentTG > 0U) {
|
||||||
}
|
|
||||||
else if (dstId != currentId) {
|
|
||||||
CP25Reflector* reflector = NULL;
|
|
||||||
if (dstId != 9999U)
|
|
||||||
reflector = reflectors.find(dstId);
|
|
||||||
|
|
||||||
// If we're unlinking or changing reflectors, unlink from the current one
|
|
||||||
if (dstId == 9999U || reflector != NULL) {
|
|
||||||
std::string callsign = lookup->find(srcId);
|
std::string callsign = lookup->find(srcId);
|
||||||
|
LogMessage("Unlinking from reflector %u by %s", currentTG, callsign.c_str());
|
||||||
|
|
||||||
if (currentId != 9999U) {
|
if (!currentIsStatic) {
|
||||||
LogMessage("Unlinked from reflector %u by %s", currentId, callsign.c_str());
|
|
||||||
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
||||||
|
|
||||||
inactivityTimer.stop();
|
|
||||||
pollTimer.stop();
|
|
||||||
lostTimer.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voice != NULL) {
|
hangTimer.stop();
|
||||||
if (dstId == 9999U)
|
}
|
||||||
voice->unlinked();
|
|
||||||
else
|
|
||||||
voice->linkedTo(dstId);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentId = dstId;
|
const CStaticTG* found = NULL;
|
||||||
|
for (std::vector<CStaticTG>::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it) {
|
||||||
|
if (dstTG == (*it).m_tg) {
|
||||||
|
found = &(*it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTG = 0U;
|
||||||
|
currentAddrLen = 0U;
|
||||||
|
|
||||||
|
if (found == NULL) {
|
||||||
|
CP25Reflector* refl = reflectors.find(dstTG);
|
||||||
|
if (refl != NULL) {
|
||||||
|
currentTG = dstTG;
|
||||||
|
currentAddr = refl->m_addr;
|
||||||
|
currentAddrLen = refl->m_addrLen;
|
||||||
|
currentIsStatic = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentTG = found->m_tg;
|
||||||
|
currentAddr = found->m_addr;
|
||||||
|
currentAddrLen = found->m_addrLen;
|
||||||
|
currentIsStatic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link to the new reflector
|
// Link to the new reflector
|
||||||
if (reflector != NULL) {
|
if (currentAddrLen > 0U) {
|
||||||
currentId = dstId;
|
|
||||||
currentAddr = reflector->m_addr;
|
|
||||||
currentAddrLen = reflector->m_addrLen;
|
|
||||||
|
|
||||||
std::string callsign = lookup->find(srcId);
|
std::string callsign = lookup->find(srcId);
|
||||||
LogMessage("Linked to reflector %u by %s", currentId, callsign.c_str());
|
LogMessage("Switched to reflector %u due to RF activity from %s", currentTG, callsign.c_str());
|
||||||
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
if (!currentIsStatic) {
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
||||||
|
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
||||||
|
}
|
||||||
|
|
||||||
inactivityTimer.start();
|
hangTimer.setTimeout(rfHangTime);
|
||||||
pollTimer.start();
|
hangTimer.start();
|
||||||
lostTimer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (voice != NULL) {
|
||||||
|
if (currentTG == 0U)
|
||||||
|
voice->unlinked();
|
||||||
|
else
|
||||||
|
voice->linkedTo(dstTG);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (buffer[0U] == 0x80U) {
|
}
|
||||||
|
|
||||||
|
if (buffer[0U] == 0x80U) {
|
||||||
if (voice != NULL)
|
if (voice != NULL)
|
||||||
voice->eof();
|
voice->eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're linked and we have a network, send it on
|
// If we're linked and we have a network, send it on
|
||||||
if (currentId != 9999U) {
|
if (currentTG > 0U) {
|
||||||
// Rewrite the LCF and the destination TG
|
// Rewrite the LCF and the destination TG
|
||||||
if (buffer[0U] == 0x64U) {
|
if (buffer[0U] == 0x64U) {
|
||||||
buffer[1U] = 0x00U; // LCF is for TGs
|
buffer[1U] = 0x00U; // LCF is for TGs
|
||||||
} else if (buffer[0U] == 0x65U) {
|
} else if (buffer[0U] == 0x65U) {
|
||||||
buffer[1U] = (currentId >> 16) & 0xFFU;
|
buffer[1U] = (currentTG >> 16) & 0xFFU;
|
||||||
buffer[2U] = (currentId >> 8) & 0xFFU;
|
buffer[2U] = (currentTG >> 8) & 0xFFU;
|
||||||
buffer[3U] = (currentId >> 0) & 0xFFU;
|
buffer[3U] = (currentTG >> 0) & 0xFFU;
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteNetwork.writeData(buffer, len, currentAddr, currentAddrLen);
|
remoteNetwork.writeData(buffer, len, currentAddr, currentAddrLen);
|
||||||
inactivityTimer.start();
|
hangTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,167 +434,49 @@ void CP25Gateway::run()
|
|||||||
|
|
||||||
reflectors.clock(ms);
|
reflectors.clock(ms);
|
||||||
|
|
||||||
if (remoteSocket != NULL) {
|
|
||||||
int res = remoteSocket->read(buffer, 200U, addr, addrlen);
|
|
||||||
if (res > 0) {
|
|
||||||
buffer[res] = '\0';
|
|
||||||
if (::memcmp(buffer + 0U, "TalkGroup", 9U) == 0) {
|
|
||||||
unsigned int tg = (unsigned int)::atoi((char*)(buffer + 9U));
|
|
||||||
|
|
||||||
CP25Reflector* reflector = NULL;
|
|
||||||
if (tg != 9999U)
|
|
||||||
reflector = reflectors.find(tg);
|
|
||||||
|
|
||||||
if (reflector == NULL && currentId != 9999U) {
|
|
||||||
LogMessage("Unlinked from reflector %u by remote command", currentId);
|
|
||||||
|
|
||||||
if (voice != NULL) {
|
|
||||||
voice->unlinked();
|
|
||||||
voice->eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
|
|
||||||
inactivityTimer.stop();
|
|
||||||
pollTimer.stop();
|
|
||||||
lostTimer.stop();
|
|
||||||
|
|
||||||
currentId = 9999U;
|
|
||||||
} else if (reflector != NULL && currentId == 9999U) {
|
|
||||||
currentId = tg;
|
|
||||||
currentAddr = reflector->m_addr;
|
|
||||||
currentAddrLen = reflector->m_addrLen;
|
|
||||||
|
|
||||||
LogMessage("Linked to reflector %u by remote command", currentId);
|
|
||||||
|
|
||||||
if (voice != NULL) {
|
|
||||||
voice->linkedTo(currentId);
|
|
||||||
voice->eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
|
|
||||||
inactivityTimer.start();
|
|
||||||
pollTimer.start();
|
|
||||||
lostTimer.start();
|
|
||||||
} else if (reflector != NULL && currentId != 9999U) {
|
|
||||||
LogMessage("Unlinked from reflector %u by remote command", currentId);
|
|
||||||
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
|
|
||||||
currentId = tg;
|
|
||||||
currentAddr = reflector->m_addr;
|
|
||||||
currentAddrLen = reflector->m_addrLen;
|
|
||||||
|
|
||||||
LogMessage("Linked to reflector %u by remote command", currentId);
|
|
||||||
|
|
||||||
if (voice != NULL) {
|
|
||||||
voice->linkedTo(currentId);
|
|
||||||
voice->eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
|
|
||||||
inactivityTimer.start();
|
|
||||||
pollTimer.start();
|
|
||||||
lostTimer.start();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CUtils::dump("Invalid remote command received", buffer, res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (voice != NULL)
|
if (voice != NULL)
|
||||||
voice->clock(ms);
|
voice->clock(ms);
|
||||||
|
|
||||||
inactivityTimer.clock(ms);
|
hangTimer.clock(ms);
|
||||||
if (inactivityTimer.isRunning() && inactivityTimer.hasExpired()) {
|
if (hangTimer.isRunning() && hangTimer.hasExpired()) {
|
||||||
if (currentId != 9999U && startupId == 9999U) {
|
if (currentTG > 0U) {
|
||||||
LogMessage("Unlinking from %u due to inactivity", currentId);
|
LogMessage("Unlinking from %u due to inactivity", currentTG);
|
||||||
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
if (!currentIsStatic) {
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
||||||
|
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
||||||
|
}
|
||||||
|
|
||||||
if (voice != NULL)
|
if (voice != NULL)
|
||||||
voice->unlinked();
|
voice->unlinked();
|
||||||
currentId = 9999U;
|
|
||||||
|
|
||||||
pollTimer.stop();
|
currentTG = 0U;
|
||||||
lostTimer.stop();
|
currentAddrLen = 0U;
|
||||||
inactivityTimer.stop();
|
|
||||||
} else if (currentId != startupId) {
|
|
||||||
if (currentId != 9999U) {
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writeUnlink(currentAddr, currentAddrLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
CP25Reflector* reflector = reflectors.find(startupId);
|
hangTimer.stop();
|
||||||
if (reflector != NULL) {
|
|
||||||
currentId = startupId;
|
|
||||||
currentAddr = reflector->m_addr;
|
|
||||||
currentAddrLen = reflector->m_addrLen;
|
|
||||||
|
|
||||||
inactivityTimer.start();
|
|
||||||
pollTimer.start();
|
|
||||||
lostTimer.start();
|
|
||||||
|
|
||||||
LogMessage("Linked to reflector %u due to inactivity", currentId);
|
|
||||||
|
|
||||||
if (voice != NULL)
|
|
||||||
voice->linkedTo(currentId);
|
|
||||||
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
|
||||||
} else {
|
|
||||||
startupId = 9999U;
|
|
||||||
inactivityTimer.stop();
|
|
||||||
pollTimer.stop();
|
|
||||||
lostTimer.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pollTimer.clock(ms);
|
pollTimer.clock(ms);
|
||||||
if (pollTimer.isRunning() && pollTimer.hasExpired()) {
|
if (pollTimer.isRunning() && pollTimer.hasExpired()) {
|
||||||
if (currentId != 9999U)
|
// Poll the static TGs
|
||||||
|
for (std::vector<CStaticTG>::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it)
|
||||||
|
remoteNetwork.writePoll((*it).m_addr, (*it).m_addrLen);
|
||||||
|
|
||||||
|
// Poll the dynamic TG
|
||||||
|
if (!currentIsStatic && currentAddrLen > 0U)
|
||||||
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
remoteNetwork.writePoll(currentAddr, currentAddrLen);
|
||||||
|
|
||||||
pollTimer.start();
|
pollTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
lostTimer.clock(ms);
|
|
||||||
if (lostTimer.isRunning() && lostTimer.hasExpired()) {
|
|
||||||
if (currentId != 9999U) {
|
|
||||||
LogWarning("No response from %u, unlinking", currentId);
|
|
||||||
currentId = 9999U;
|
|
||||||
}
|
|
||||||
|
|
||||||
inactivityTimer.stop();
|
|
||||||
lostTimer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ms < 5U)
|
if (ms < 5U)
|
||||||
CThread::sleep(5U);
|
CThread::sleep(5U);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete voice;
|
delete voice;
|
||||||
|
|
||||||
if (remoteSocket != NULL) {
|
|
||||||
remoteSocket->close();
|
|
||||||
delete remoteSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
localNetwork.close();
|
localNetwork.close();
|
||||||
|
|
||||||
remoteNetwork.close();
|
remoteNetwork.close();
|
||||||
|
@ -3,6 +3,7 @@ Callsign=G4KLX
|
|||||||
RptAddress=127.0.0.1
|
RptAddress=127.0.0.1
|
||||||
RptPort=32010
|
RptPort=32010
|
||||||
LocalPort=42020
|
LocalPort=42020
|
||||||
|
Debug=0
|
||||||
Daemon=1
|
Daemon=1
|
||||||
|
|
||||||
[Id Lookup]
|
[Id Lookup]
|
||||||
@ -30,10 +31,7 @@ ParrotAddress=127.0.0.1
|
|||||||
ParrotPort=42011
|
ParrotPort=42011
|
||||||
P252DMRAddress=127.0.0.1
|
P252DMRAddress=127.0.0.1
|
||||||
P252DMRPort=42012
|
P252DMRPort=42012
|
||||||
# Startup=10100
|
Static=10100,10200,10300,10400
|
||||||
InactivityTimeout=10
|
RFHangTime=120
|
||||||
|
NetHangTime=60
|
||||||
Debug=0
|
Debug=0
|
||||||
|
|
||||||
[Remote Commands]
|
|
||||||
Enable=0
|
|
||||||
Port=6074
|
|
||||||
|
@ -19,6 +19,6 @@
|
|||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20200920";
|
const char* VERSION = "20201026";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user