mirror of
https://github.com/g4klx/DMRGateway
synced 2025-12-21 05:25:40 +08:00
Simplify the Host to DMR Gateway protocol.
This commit is contained in:
74
Conf.cpp
74
Conf.cpp
@@ -38,7 +38,8 @@ enum SECTION {
|
||||
SECTION_DMR_NETWORK_4,
|
||||
SECTION_DMR_NETWORK_5,
|
||||
SECTION_XLX_NETWORK,
|
||||
SECTION_DYNAMIC_TG_CONTROL
|
||||
SECTION_DYNAMIC_TG_CONTROL,
|
||||
SECTION_GPSD,
|
||||
};
|
||||
|
||||
CConf::CConf(const std::string& file) :
|
||||
@@ -59,14 +60,9 @@ m_logDisplayLevel(0U),
|
||||
m_logFileLevel(0U),
|
||||
m_logFilePath(),
|
||||
m_logFileRoot(),
|
||||
m_infoEnabled(false),
|
||||
m_infoRXFrequency(0U),
|
||||
m_infoTXFrequency(0U),
|
||||
m_infoPower(0U),
|
||||
m_infoLatitude(0.0F),
|
||||
m_infoLongitude(0.0F),
|
||||
m_infoHeight(0),
|
||||
m_infoLocation(),
|
||||
m_infoDescription(),
|
||||
m_infoURL(),
|
||||
m_dmrNetwork1Enabled(false),
|
||||
@@ -175,7 +171,10 @@ m_xlxNetworkDebug(false),
|
||||
m_xlxNetworkUserControl(true),
|
||||
m_xlxNetworkModule(),
|
||||
m_dynamicTGControlEnabled(false),
|
||||
m_dynamicTGControlPort(3769U)
|
||||
m_dynamicTGControlPort(3769U),
|
||||
m_gpsdEnabled(false),
|
||||
m_gpsdAddress(),
|
||||
m_gpsdPort()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -221,6 +220,8 @@ bool CConf::read()
|
||||
section = SECTION_DMR_NETWORK_5;
|
||||
else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0)
|
||||
section = SECTION_DYNAMIC_TG_CONTROL;
|
||||
else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
||||
section = SECTION_GPSD;
|
||||
else
|
||||
section = SECTION_NONE;
|
||||
|
||||
@@ -280,22 +281,12 @@ bool CConf::read()
|
||||
else if (::strcmp(key, "Directory") == 0)
|
||||
m_voiceDirectory = value;
|
||||
} else if (section == SECTION_INFO) {
|
||||
if (::strcmp(key, "Enabled") == 0)
|
||||
m_infoEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "TXFrequency") == 0)
|
||||
m_infoTXFrequency = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "RXFrequency") == 0)
|
||||
m_infoRXFrequency = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Power") == 0)
|
||||
m_infoPower = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Latitude") == 0)
|
||||
if (::strcmp(key, "Latitude") == 0)
|
||||
m_infoLatitude = float(::atof(value));
|
||||
else if (::strcmp(key, "Longitude") == 0)
|
||||
m_infoLongitude = float(::atof(value));
|
||||
else if (::strcmp(key, "Height") == 0)
|
||||
m_infoHeight = ::atoi(value);
|
||||
else if (::strcmp(key, "Location") == 0)
|
||||
m_infoLocation = value;
|
||||
else if (::strcmp(key, "Description") == 0)
|
||||
m_infoDescription = value;
|
||||
else if (::strcmp(key, "URL") == 0)
|
||||
@@ -946,6 +937,13 @@ bool CConf::read()
|
||||
m_dynamicTGControlEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Port") == 0)
|
||||
m_dynamicTGControlPort = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_GPSD) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_gpsdEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Address") == 0)
|
||||
m_gpsdAddress = value;
|
||||
else if (::strcmp(key, "Port") == 0)
|
||||
m_gpsdPort = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,26 +1032,6 @@ std::string CConf::getVoiceDirectory() const
|
||||
return m_voiceDirectory;
|
||||
}
|
||||
|
||||
bool CConf::getInfoEnabled() const
|
||||
{
|
||||
return m_infoEnabled;
|
||||
}
|
||||
|
||||
unsigned int CConf::getInfoRXFrequency() const
|
||||
{
|
||||
return m_infoRXFrequency;
|
||||
}
|
||||
|
||||
unsigned int CConf::getInfoTXFrequency() const
|
||||
{
|
||||
return m_infoTXFrequency;
|
||||
}
|
||||
|
||||
unsigned int CConf::getInfoPower() const
|
||||
{
|
||||
return m_infoPower;
|
||||
}
|
||||
|
||||
float CConf::getInfoLatitude() const
|
||||
{
|
||||
return m_infoLatitude;
|
||||
@@ -1069,11 +1047,6 @@ int CConf::getInfoHeight() const
|
||||
return m_infoHeight;
|
||||
}
|
||||
|
||||
std::string CConf::getInfoLocation() const
|
||||
{
|
||||
return m_infoLocation;
|
||||
}
|
||||
|
||||
std::string CConf::getInfoDescription() const
|
||||
{
|
||||
return m_infoDescription;
|
||||
@@ -1631,3 +1604,18 @@ unsigned int CConf::getDynamicTGControlPort() const
|
||||
{
|
||||
return m_dynamicTGControlPort;
|
||||
}
|
||||
|
||||
bool CConf::getGPSDEnabled() const
|
||||
{
|
||||
return m_gpsdEnabled;
|
||||
}
|
||||
|
||||
std::string CConf::getGPSDAddress() const
|
||||
{
|
||||
return m_gpsdAddress;
|
||||
}
|
||||
|
||||
std::string CConf::getGPSDPort() const
|
||||
{
|
||||
return m_gpsdPort;
|
||||
}
|
||||
|
||||
19
Conf.h
19
Conf.h
@@ -100,14 +100,9 @@ public:
|
||||
std::string getVoiceDirectory() const;
|
||||
|
||||
// The Info section
|
||||
bool getInfoEnabled() const;
|
||||
unsigned int getInfoRXFrequency() const;
|
||||
unsigned int getInfoTXFrequency() const;
|
||||
unsigned int getInfoPower() const;
|
||||
float getInfoLatitude() const;
|
||||
float getInfoLongitude() const;
|
||||
int getInfoHeight() const;
|
||||
std::string getInfoLocation() const;
|
||||
std::string getInfoDescription() const;
|
||||
std::string getInfoURL() const;
|
||||
|
||||
@@ -232,6 +227,11 @@ public:
|
||||
bool getDynamicTGControlEnabled() const;
|
||||
unsigned int getDynamicTGControlPort() const;
|
||||
|
||||
// The GPSD section
|
||||
bool getGPSDEnabled() const;
|
||||
std::string getGPSDAddress() const;
|
||||
std::string getGPSDPort() const;
|
||||
|
||||
private:
|
||||
std::string m_file;
|
||||
bool m_daemon;
|
||||
@@ -253,14 +253,9 @@ private:
|
||||
std::string m_logFilePath;
|
||||
std::string m_logFileRoot;
|
||||
|
||||
bool m_infoEnabled;
|
||||
unsigned int m_infoRXFrequency;
|
||||
unsigned int m_infoTXFrequency;
|
||||
unsigned int m_infoPower;
|
||||
float m_infoLatitude;
|
||||
float m_infoLongitude;
|
||||
int m_infoHeight;
|
||||
std::string m_infoLocation;
|
||||
std::string m_infoDescription;
|
||||
std::string m_infoURL;
|
||||
|
||||
@@ -377,6 +372,10 @@ private:
|
||||
|
||||
bool m_dynamicTGControlEnabled;
|
||||
unsigned int m_dynamicTGControlPort;
|
||||
|
||||
bool m_gpsdEnabled;
|
||||
std::string m_gpsdAddress;
|
||||
std::string m_gpsdPort;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
160
DMRGateway.cpp
160
DMRGateway.cpp
@@ -182,6 +182,9 @@ m_dmr5Passalls(),
|
||||
m_dynVoices(),
|
||||
m_dynRF(),
|
||||
m_socket(NULL)
|
||||
#if defined(USE_GPSD)
|
||||
,m_gpsd(NULL)
|
||||
#endif
|
||||
{
|
||||
m_status = new DMRGW_STATUS[3U];
|
||||
m_status[1U] = DMRGWS_NONE;
|
||||
@@ -354,7 +357,7 @@ int CDMRGateway::run()
|
||||
LogMessage("Waiting for MMDVM to connect.....");
|
||||
|
||||
while (!m_killed) {
|
||||
m_configLen = m_repeater->getConfig(m_config);
|
||||
m_configLen = m_repeater->getShortConfig(m_config);
|
||||
if (m_configLen > 0U && m_repeater->getId() > 1000U)
|
||||
break;
|
||||
|
||||
@@ -371,6 +374,26 @@ int CDMRGateway::run()
|
||||
|
||||
LogMessage("MMDVM has connected");
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
bool gpsdEnabled = m_conf.getGPSDEnabled();
|
||||
if (gpsdEnabled) {
|
||||
std::string gpsdAddress = m_conf.getGPSDAddress();
|
||||
std::string gpsdPort = m_conf.getGPSDPort();
|
||||
|
||||
LogInfo("GPSD Parameters");
|
||||
LogInfo(" Address: %s", gpsdAddress.c_str());
|
||||
LogInfo(" Port: %s", gpsdPort.c_str());
|
||||
|
||||
m_gpsd = new CGPSD(gpsdAddress, gpsdPort, m_dmrNetwork);
|
||||
|
||||
ret = m_gpsd->open();
|
||||
if (!ret) {
|
||||
delete m_gpsd;
|
||||
m_gpsd = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ruleTrace = m_conf.getRuleTrace();
|
||||
LogInfo("Rule trace: %s", ruleTrace ? "yes" : "no");
|
||||
|
||||
@@ -1131,8 +1154,6 @@ int CDMRGateway::run()
|
||||
|
||||
processTalkerAlias();
|
||||
|
||||
processHomePosition();
|
||||
|
||||
if (xlxVoice != NULL) {
|
||||
ret = xlxVoice->read(data);
|
||||
if (ret) {
|
||||
@@ -1183,6 +1204,11 @@ int CDMRGateway::run()
|
||||
if (xlxVoice != NULL)
|
||||
xlxVoice->clock(ms);
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (m_gpsd != NULL)
|
||||
m_gpsd->clock(ms);
|
||||
#endif
|
||||
|
||||
for (std::vector<CDynVoice*>::iterator it = m_dynVoices.begin(); it != m_dynVoices.end(); ++it)
|
||||
(*it)->clock(ms);
|
||||
|
||||
@@ -1203,6 +1229,13 @@ int CDMRGateway::run()
|
||||
m_repeater->close();
|
||||
delete m_repeater;
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (m_gpsd != NULL) {
|
||||
m_gpsd->close();
|
||||
delete m_gpsd;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_dmrNetwork1 != NULL) {
|
||||
m_dmrNetwork1->close();
|
||||
delete m_dmrNetwork1;
|
||||
@@ -1297,11 +1330,9 @@ bool CDMRGateway::createDMRNetwork1()
|
||||
LogInfo(" Local: random");
|
||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
||||
|
||||
m_dmrNetwork1 = new CDMRNetwork(address, port, local, id, password, m_dmr1Name, VERSION, debug);
|
||||
m_dmrNetwork1 = new CDMRNetwork(address, port, local, id, password, m_dmr1Name, VERSION, location, debug);
|
||||
|
||||
std::string options = m_conf.getDMRNetwork1Options();
|
||||
if (options.empty())
|
||||
options = m_repeater->getOptions();
|
||||
|
||||
if (!options.empty()) {
|
||||
LogInfo(" Options: %s", options.c_str());
|
||||
@@ -1310,10 +1341,6 @@ bool CDMRGateway::createDMRNetwork1()
|
||||
|
||||
unsigned char config[400U];
|
||||
unsigned int len = getConfig(m_dmr1Name, config);
|
||||
|
||||
if (!location)
|
||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
||||
|
||||
m_dmrNetwork1->setConfig(config, len);
|
||||
|
||||
bool ret = m_dmrNetwork1->open();
|
||||
@@ -1323,6 +1350,11 @@ bool CDMRGateway::createDMRNetwork1()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (location)
|
||||
m_gpsd->addNetwork(m_dmrNetwork1);
|
||||
#endif
|
||||
|
||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork1TGRewrites();
|
||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||
if ((*it).m_range == 1)
|
||||
@@ -1465,11 +1497,9 @@ bool CDMRGateway::createDMRNetwork2()
|
||||
LogInfo(" Local: random");
|
||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
||||
|
||||
m_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, m_dmr2Name, VERSION, debug);
|
||||
m_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, m_dmr2Name, VERSION, location, debug);
|
||||
|
||||
std::string options = m_conf.getDMRNetwork2Options();
|
||||
if (options.empty())
|
||||
options = m_repeater->getOptions();
|
||||
|
||||
if (!options.empty()) {
|
||||
LogInfo(" Options: %s", options.c_str());
|
||||
@@ -1479,9 +1509,6 @@ bool CDMRGateway::createDMRNetwork2()
|
||||
unsigned char config[400U];
|
||||
unsigned int len = getConfig(m_dmr2Name, config);
|
||||
|
||||
if (!location)
|
||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
||||
|
||||
m_dmrNetwork2->setConfig(config, len);
|
||||
|
||||
bool ret = m_dmrNetwork2->open();
|
||||
@@ -1491,6 +1518,11 @@ bool CDMRGateway::createDMRNetwork2()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (location)
|
||||
m_gpsd->addNetwork(m_dmrNetwork2);
|
||||
#endif
|
||||
|
||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork2TGRewrites();
|
||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||
if ((*it).m_range == 1)
|
||||
@@ -1633,11 +1665,9 @@ bool CDMRGateway::createDMRNetwork3()
|
||||
LogInfo(" Local: random");
|
||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
||||
|
||||
m_dmrNetwork3 = new CDMRNetwork(address, port, local, id, password, m_dmr3Name, VERSION, debug);
|
||||
m_dmrNetwork3 = new CDMRNetwork(address, port, local, id, password, m_dmr3Name, VERSION, location, debug);
|
||||
|
||||
std::string options = m_conf.getDMRNetwork3Options();
|
||||
if (options.empty())
|
||||
options = m_repeater->getOptions();
|
||||
|
||||
if (!options.empty()) {
|
||||
LogInfo(" Options: %s", options.c_str());
|
||||
@@ -1646,10 +1676,6 @@ bool CDMRGateway::createDMRNetwork3()
|
||||
|
||||
unsigned char config[400U];
|
||||
unsigned int len = getConfig(m_dmr3Name, config);
|
||||
|
||||
if (!location)
|
||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
||||
|
||||
m_dmrNetwork3->setConfig(config, len);
|
||||
|
||||
bool ret = m_dmrNetwork3->open();
|
||||
@@ -1659,6 +1685,11 @@ bool CDMRGateway::createDMRNetwork3()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (location)
|
||||
m_gpsd->addNetwork(m_dmrNetwork3);
|
||||
#endif
|
||||
|
||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork3TGRewrites();
|
||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||
if ((*it).m_range == 1)
|
||||
@@ -1801,11 +1832,9 @@ bool CDMRGateway::createDMRNetwork4()
|
||||
LogInfo(" Local: random");
|
||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
||||
|
||||
m_dmrNetwork4 = new CDMRNetwork(address, port, local, id, password, m_dmr4Name, VERSION, debug);
|
||||
m_dmrNetwork4 = new CDMRNetwork(address, port, local, id, password, m_dmr4Name, VERSION, location, debug);
|
||||
|
||||
std::string options = m_conf.getDMRNetwork4Options();
|
||||
if (options.empty())
|
||||
options = m_repeater->getOptions();
|
||||
|
||||
if (!options.empty()) {
|
||||
LogInfo(" Options: %s", options.c_str());
|
||||
@@ -1814,10 +1843,6 @@ bool CDMRGateway::createDMRNetwork4()
|
||||
|
||||
unsigned char config[400U];
|
||||
unsigned int len = getConfig(m_dmr4Name, config);
|
||||
|
||||
if (!location)
|
||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
||||
|
||||
m_dmrNetwork4->setConfig(config, len);
|
||||
|
||||
bool ret = m_dmrNetwork4->open();
|
||||
@@ -1827,6 +1852,11 @@ bool CDMRGateway::createDMRNetwork4()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (location)
|
||||
m_gpsd->addNetwork(m_dmrNetwork4);
|
||||
#endif
|
||||
|
||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork4TGRewrites();
|
||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||
if ((*it).m_range == 1)
|
||||
@@ -1969,11 +1999,9 @@ bool CDMRGateway::createDMRNetwork5()
|
||||
LogInfo(" Local: random");
|
||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
||||
|
||||
m_dmrNetwork5 = new CDMRNetwork(address, port, local, id, password, m_dmr5Name, VERSION, debug);
|
||||
m_dmrNetwork5 = new CDMRNetwork(address, port, local, id, password, m_dmr5Name, VERSION, location, debug);
|
||||
|
||||
std::string options = m_conf.getDMRNetwork5Options();
|
||||
if (options.empty())
|
||||
options = m_repeater->getOptions();
|
||||
|
||||
if (!options.empty()) {
|
||||
LogInfo(" Options: %s", options.c_str());
|
||||
@@ -1982,10 +2010,6 @@ bool CDMRGateway::createDMRNetwork5()
|
||||
|
||||
unsigned char config[400U];
|
||||
unsigned int len = getConfig(m_dmr5Name, config);
|
||||
|
||||
if (!location)
|
||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
||||
|
||||
m_dmrNetwork5->setConfig(config, len);
|
||||
|
||||
bool ret = m_dmrNetwork5->open();
|
||||
@@ -1995,6 +2019,11 @@ bool CDMRGateway::createDMRNetwork5()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
if (location)
|
||||
m_gpsd->addNetwork(m_dmrNetwork5);
|
||||
#endif
|
||||
|
||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork5TGRewrites();
|
||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||
if ((*it).m_range == 1)
|
||||
@@ -2213,7 +2242,7 @@ bool CDMRGateway::linkXLX(unsigned int number)
|
||||
m_xlxConnected = false;
|
||||
m_xlxRelink.stop();
|
||||
|
||||
m_xlxNetwork = new CDMRNetwork(reflector->m_address, m_xlxPort, m_xlxLocal, m_xlxId, m_xlxPassword, "XLX", VERSION, m_xlxDebug);
|
||||
m_xlxNetwork = new CDMRNetwork(reflector->m_address, m_xlxPort, m_xlxLocal, m_xlxId, m_xlxPassword, "XLX", VERSION, false, m_xlxDebug);
|
||||
|
||||
unsigned char config[400U];
|
||||
unsigned int len = getConfig("XLX", config);
|
||||
@@ -2319,16 +2348,6 @@ unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buff
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
|
||||
bool enabled = m_conf.getInfoEnabled();
|
||||
|
||||
if (!enabled) {
|
||||
LogInfo("%s: Using original configuration message: %*s", name.c_str(), m_configLen, m_config);
|
||||
::memcpy(buffer, m_config, m_configLen);
|
||||
return m_configLen;
|
||||
}
|
||||
|
||||
LogInfo("%s: Original configuration message: %*s", name.c_str(), m_configLen, m_config);
|
||||
|
||||
char latitude[20U];
|
||||
float lat = m_conf.getInfoLatitude();
|
||||
::sprintf(latitude, "%08f", lat);
|
||||
@@ -2337,25 +2356,18 @@ unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buff
|
||||
float lon = m_conf.getInfoLongitude();
|
||||
::sprintf(longitude, "%09f", lon);
|
||||
|
||||
unsigned int power = m_conf.getInfoPower();
|
||||
if (power > 99U)
|
||||
power = 99U;
|
||||
|
||||
int height = m_conf.getInfoHeight();
|
||||
if (height > 999)
|
||||
height = 999;
|
||||
|
||||
unsigned int rxFrequency = m_conf.getInfoRXFrequency();
|
||||
unsigned int txFrequency = m_conf.getInfoTXFrequency();
|
||||
std::string location = m_conf.getInfoLocation();
|
||||
std::string description = m_conf.getInfoDescription();
|
||||
std::string url = m_conf.getInfoURL();
|
||||
|
||||
::sprintf((char*)buffer, "%-8.8s%09u%09u%02u%2.2s%8.8s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%-40.40s%-40.40s", m_config + 0U,
|
||||
rxFrequency, txFrequency, power, m_config + 28U, latitude, longitude, height, location.c_str(),
|
||||
description.c_str(), m_config[89U], url.c_str(), m_config + 214U, m_config + 254U);
|
||||
::sprintf((char*)buffer, "%30.30s%9.9s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%80.80s",
|
||||
m_config + 0U, latitude, longitude, height, m_config + 30U,
|
||||
description.c_str(), m_config[50U], url.c_str(), m_config + 51U);
|
||||
|
||||
LogInfo("%s: New configuration message: %s", name.c_str(), buffer);
|
||||
LogInfo("%s: configuration message: %s", name.c_str(), buffer);
|
||||
|
||||
return (unsigned int)::strlen((char*)buffer);
|
||||
}
|
||||
@@ -2368,9 +2380,6 @@ void CDMRGateway::processRadioPosition()
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
if (m_xlxNetwork != NULL && (m_status[1U] == DMRGWS_XLXREFLECTOR || m_status[2U] == DMRGWS_XLXREFLECTOR))
|
||||
m_xlxNetwork->writeRadioPosition(buffer, length);
|
||||
|
||||
if (m_dmrNetwork1 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1))
|
||||
m_dmrNetwork1->writeRadioPosition(buffer, length);
|
||||
|
||||
@@ -2414,33 +2423,6 @@ void CDMRGateway::processTalkerAlias()
|
||||
m_dmrNetwork5->writeTalkerAlias(buffer, length);
|
||||
}
|
||||
|
||||
void CDMRGateway::processHomePosition()
|
||||
{
|
||||
unsigned char buffer[50U];
|
||||
unsigned int length;
|
||||
bool ret = m_repeater->readHomePosition(buffer, length);
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
if (m_xlxNetwork != NULL)
|
||||
m_xlxNetwork->writeHomePosition(buffer, length);
|
||||
|
||||
if (m_dmrNetwork1 != NULL)
|
||||
m_dmrNetwork1->writeHomePosition(buffer, length);
|
||||
|
||||
if (m_dmrNetwork2 != NULL)
|
||||
m_dmrNetwork2->writeHomePosition(buffer, length);
|
||||
|
||||
if (m_dmrNetwork3 != NULL)
|
||||
m_dmrNetwork3->writeHomePosition(buffer, length);
|
||||
|
||||
if (m_dmrNetwork4 != NULL)
|
||||
m_dmrNetwork4->writeHomePosition(buffer, length);
|
||||
|
||||
if (m_dmrNetwork5 != NULL)
|
||||
m_dmrNetwork5->writeHomePosition(buffer, length);
|
||||
}
|
||||
|
||||
void CDMRGateway::processDynamicTGControl()
|
||||
{
|
||||
unsigned char buffer[100U];
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#if !defined(DMRGateway_H)
|
||||
#define DMRGateway_H
|
||||
|
||||
#include "RepeaterProtocol.h"
|
||||
#include "RewriteDynTGNet.h"
|
||||
#include "RewriteDynTGRF.h"
|
||||
#include "MMDVMNetwork.h"
|
||||
@@ -31,6 +30,7 @@
|
||||
#include "Rewrite.h"
|
||||
#include "Timer.h"
|
||||
#include "Conf.h"
|
||||
#include "GPSD.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
private:
|
||||
CConf m_conf;
|
||||
DMRGW_STATUS* m_status;
|
||||
IRepeaterProtocol* m_repeater;
|
||||
CMMDVMNetwork* m_repeater;
|
||||
unsigned char* m_config;
|
||||
unsigned int m_configLen;
|
||||
CDMRNetwork* m_dmrNetwork1;
|
||||
@@ -111,6 +111,9 @@ private:
|
||||
std::vector<CDynVoice*> m_dynVoices;
|
||||
std::vector<CRewriteDynTGRF*> m_dynRF;
|
||||
CUDPSocket* m_socket;
|
||||
#if defined(USE_GPSD)
|
||||
CGPSD* m_gpsd;
|
||||
#endif
|
||||
|
||||
bool createMMDVM();
|
||||
bool createDMRNetwork1();
|
||||
@@ -131,7 +134,6 @@ private:
|
||||
|
||||
void processRadioPosition();
|
||||
void processTalkerAlias();
|
||||
void processHomePosition();
|
||||
void processDynamicTGControl();
|
||||
};
|
||||
|
||||
|
||||
@@ -23,14 +23,9 @@ Language=en_GB
|
||||
Directory=./Audio
|
||||
|
||||
[Info]
|
||||
Enabled=0
|
||||
RXFrequency=435000000
|
||||
TXFrequency=435000000
|
||||
Power=1
|
||||
Latitude=0.0
|
||||
Longitude=0.0
|
||||
Height=0
|
||||
Location=Nowhere
|
||||
Description=Multi-Mode Repeater
|
||||
URL=www.google.co.uk
|
||||
|
||||
@@ -137,6 +132,11 @@ Password=PASSWORD
|
||||
Location=0
|
||||
Debug=0
|
||||
|
||||
[GPSD]
|
||||
Enable=0
|
||||
Address=127.0.0.1
|
||||
Port=2947
|
||||
|
||||
[Dynamic TG Control]
|
||||
Enabled=1
|
||||
Port=3769
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
<ClInclude Include="DMRSlotType.h" />
|
||||
<ClInclude Include="DynVoice.h" />
|
||||
<ClInclude Include="Golay2087.h" />
|
||||
<ClInclude Include="GPSD.h" />
|
||||
<ClInclude Include="Hamming.h" />
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="MMDVMNetwork.h" />
|
||||
@@ -175,7 +176,6 @@
|
||||
<ClInclude Include="PassAllTG.h" />
|
||||
<ClInclude Include="QR1676.h" />
|
||||
<ClInclude Include="Reflectors.h" />
|
||||
<ClInclude Include="RepeaterProtocol.h" />
|
||||
<ClInclude Include="Rewrite.h" />
|
||||
<ClInclude Include="RewriteDstId.h" />
|
||||
<ClInclude Include="RewriteDynTGNet.h" />
|
||||
@@ -213,6 +213,7 @@
|
||||
<ClCompile Include="DMRSlotType.cpp" />
|
||||
<ClCompile Include="DynVoice.cpp" />
|
||||
<ClCompile Include="Golay2087.cpp" />
|
||||
<ClCompile Include="GPSD.cpp" />
|
||||
<ClCompile Include="Hamming.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="MMDVMNetwork.cpp" />
|
||||
@@ -220,7 +221,6 @@
|
||||
<ClCompile Include="PassAllTG.cpp" />
|
||||
<ClCompile Include="QR1676.cpp" />
|
||||
<ClCompile Include="Reflectors.cpp" />
|
||||
<ClCompile Include="RepeaterProtocol.cpp" />
|
||||
<ClCompile Include="Rewrite.cpp" />
|
||||
<ClCompile Include="RewriteDstId.cpp" />
|
||||
<ClCompile Include="RewriteDynTGNet.cpp" />
|
||||
|
||||
@@ -83,9 +83,6 @@
|
||||
<ClInclude Include="CRC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RepeaterProtocol.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DMREMB.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -143,6 +140,9 @@
|
||||
<ClInclude Include="DynVoice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GPSD.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Conf.cpp">
|
||||
@@ -208,9 +208,6 @@
|
||||
<ClCompile Include="CRC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RepeaterProtocol.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DMREMB.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -268,5 +265,8 @@
|
||||
<ClCompile Include="DynVoice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GPSD.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -31,13 +31,14 @@ const unsigned int BUFFER_LENGTH = 500U;
|
||||
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||
|
||||
|
||||
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool debug) :
|
||||
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool location, bool debug) :
|
||||
m_address(),
|
||||
m_port(port),
|
||||
m_id(NULL),
|
||||
m_password(password),
|
||||
m_name(name),
|
||||
m_version(version),
|
||||
m_location(location),
|
||||
m_debug(debug),
|
||||
m_socket(local),
|
||||
m_status(WAITING_CONNECT),
|
||||
@@ -233,13 +234,16 @@ bool CDMRNetwork::writeRadioPosition(const unsigned char* data, unsigned int len
|
||||
if (m_status != RUNNING)
|
||||
return false;
|
||||
|
||||
if (!m_location)
|
||||
return false;
|
||||
|
||||
unsigned char buffer[50U];
|
||||
|
||||
::memcpy(buffer + 0U, "DMRG", 4U);
|
||||
|
||||
::memcpy(buffer + 4U, m_id, 4U);
|
||||
|
||||
::memcpy(buffer + 8U, data + 8U, length - 8U);
|
||||
::memcpy(buffer + 8U, data + 4U, length - 4U);
|
||||
|
||||
return write(buffer, length);
|
||||
}
|
||||
@@ -255,25 +259,28 @@ bool CDMRNetwork::writeTalkerAlias(const unsigned char* data, unsigned int lengt
|
||||
|
||||
::memcpy(buffer + 4U, m_id, 4U);
|
||||
|
||||
::memcpy(buffer + 8U, data + 8U, length - 8U);
|
||||
::memcpy(buffer + 8U, data + 4U, length - 4U);
|
||||
|
||||
return write(buffer, length);
|
||||
}
|
||||
|
||||
bool CDMRNetwork::writeHomePosition(const unsigned char* data, unsigned int length)
|
||||
bool CDMRNetwork::writeHomePosition(float latitude, float longitude)
|
||||
{
|
||||
if (m_status != RUNNING)
|
||||
return false;
|
||||
|
||||
unsigned char buffer[50U];
|
||||
if (!m_location)
|
||||
return false;
|
||||
|
||||
char buffer[50U];
|
||||
|
||||
::memcpy(buffer + 0U, "RPTG", 4U);
|
||||
|
||||
::memcpy(buffer + 4U, m_id, 4U);
|
||||
|
||||
::memcpy(buffer + 8U, data + 8U, length - 8U);
|
||||
::sprintf(buffer + 8U, "%08f%09f", latitude, longitude);
|
||||
|
||||
return write(buffer, length);
|
||||
return write((unsigned char*)buffer, 25U);
|
||||
}
|
||||
|
||||
bool CDMRNetwork::isConnected() const
|
||||
@@ -497,6 +504,9 @@ bool CDMRNetwork::writeConfig()
|
||||
::memset(buffer + 222U, ' ', 40U);
|
||||
::memcpy(buffer + 222U, software, ::strlen(software));
|
||||
|
||||
if (!m_location)
|
||||
::memcpy(buffer + 30U, "0.00000000.000000", 17U);
|
||||
|
||||
return write((unsigned char*)buffer, m_configLen + 8U);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -30,7 +30,7 @@
|
||||
class CDMRNetwork
|
||||
{
|
||||
public:
|
||||
CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool debug);
|
||||
CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool location, bool debug);
|
||||
~CDMRNetwork();
|
||||
|
||||
void setOptions(const std::string& options);
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
|
||||
bool writeTalkerAlias(const unsigned char* data, unsigned int length);
|
||||
|
||||
bool writeHomePosition(const unsigned char* data, unsigned int length);
|
||||
bool writeHomePosition(float latitude, float longitude);
|
||||
|
||||
bool wantsBeacon();
|
||||
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
std::string m_password;
|
||||
std::string m_name;
|
||||
const char* m_version;
|
||||
bool m_location;
|
||||
bool m_debug;
|
||||
CUDPSocket m_socket;
|
||||
|
||||
|
||||
110
GPSD.cpp
Normal file
110
GPSD.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2018,2020 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "GPSD.h"
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
CGPSD::CGPSD(const std::string& address, const std::string& port) :
|
||||
m_gpsdAddress(address),
|
||||
m_gpsdPort(port),
|
||||
m_gpsdData(),
|
||||
m_idTimer(1000U, 60U),
|
||||
m_networks()
|
||||
{
|
||||
assert(!address.empty());
|
||||
assert(!port.empty());
|
||||
}
|
||||
|
||||
CGPSD::~CGPSD()
|
||||
{
|
||||
}
|
||||
|
||||
void CGPSD::addNetwork(CDMRNetwork* network)
|
||||
{
|
||||
assert(network != NULL);
|
||||
|
||||
m_networks.push_back(network);
|
||||
}
|
||||
|
||||
bool CGPSD::open()
|
||||
{
|
||||
int ret = ::gps_open(m_gpsdAddress.c_str(), m_gpsdPort.c_str(), &m_gpsdData);
|
||||
if (ret != 0) {
|
||||
LogError("Error when opening access to gpsd - %d - %s", errno, ::gps_errstr(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL);
|
||||
|
||||
LogMessage("Connected to GPSD");
|
||||
|
||||
m_idTimer.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGPSD::clock(unsigned int ms)
|
||||
{
|
||||
m_idTimer.clock(ms);
|
||||
|
||||
if (m_idTimer.hasExpired()) {
|
||||
sendReport();
|
||||
m_idTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void CGPSD::close()
|
||||
{
|
||||
::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL);
|
||||
::gps_close(&m_gpsdData);
|
||||
}
|
||||
|
||||
void CGPSD::sendReport()
|
||||
{
|
||||
if (!::gps_waiting(&m_gpsdData, 0))
|
||||
return;
|
||||
|
||||
#if GPSD_API_MAJOR_VERSION >= 7
|
||||
if (::gps_read(&m_gpsdData, NULL, 0) <= 0)
|
||||
return;
|
||||
#else
|
||||
if (::gps_read(&m_gpsdData) <= 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (m_gpsdData.status != STATUS_FIX)
|
||||
return;
|
||||
|
||||
bool latlonSet = (m_gpsdData.set & LATLON_SET) == LATLON_SET;
|
||||
if (!latlonSet)
|
||||
return;
|
||||
|
||||
float latitude = float(m_gpsdData.fix.latitude);
|
||||
float longitude = float(m_gpsdData.fix.longitude);
|
||||
|
||||
for (std::vector<CDMRNetwork*>::const_iterator it = m_networks.begin(); it != m_networks.end(); ++it)
|
||||
(*it)->writeHomePosition(latitude, longitude);
|
||||
}
|
||||
|
||||
#endif
|
||||
57
GPSD.h
Normal file
57
GPSD.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2018,2020 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef GPSD_H
|
||||
#define GPSD_H
|
||||
|
||||
#if defined(USE_GPSD)
|
||||
|
||||
#include "DMRNetwork.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gps.h>
|
||||
|
||||
class CGPSD {
|
||||
public:
|
||||
CGPSD(const std::string& address, const std::string& port);
|
||||
~CGPSD();
|
||||
|
||||
void addNetwork(CDMRNetwork* network);
|
||||
|
||||
bool open();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
std::string m_gpsdAddress;
|
||||
std::string m_gpsdPort;
|
||||
struct gps_data_t m_gpsdData;
|
||||
CTimer m_idTimer;
|
||||
std::vector<CDMRNetwork*> m_networks;
|
||||
|
||||
void sendReport();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "MMDVMNetwork.h"
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "SHA256.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
@@ -40,15 +39,12 @@ m_debug(debug),
|
||||
m_socket(localAddress, localPort),
|
||||
m_buffer(NULL),
|
||||
m_rxData(1000U, "MMDVM Network"),
|
||||
m_options(),
|
||||
m_configData(NULL),
|
||||
m_configLen(0U),
|
||||
m_radioPositionData(NULL),
|
||||
m_radioPositionLen(0U),
|
||||
m_talkerAliasData(NULL),
|
||||
m_talkerAliasLen(0U),
|
||||
m_homePositionData(NULL),
|
||||
m_homePositionLen(0U)
|
||||
m_talkerAliasLen(0U)
|
||||
{
|
||||
assert(!rptAddress.empty());
|
||||
assert(rptPort > 0U);
|
||||
@@ -60,7 +56,6 @@ m_homePositionLen(0U)
|
||||
|
||||
m_radioPositionData = new unsigned char[50U];
|
||||
m_talkerAliasData = new unsigned char[50U];
|
||||
m_homePositionData = new unsigned char[50U];
|
||||
|
||||
CStopWatch stopWatch;
|
||||
::srand(stopWatch.start());
|
||||
@@ -73,15 +68,9 @@ CMMDVMNetwork::~CMMDVMNetwork()
|
||||
delete[] m_configData;
|
||||
delete[] m_radioPositionData;
|
||||
delete[] m_talkerAliasData;
|
||||
delete[] m_homePositionData;
|
||||
}
|
||||
|
||||
std::string CMMDVMNetwork::getOptions() const
|
||||
{
|
||||
return m_options;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetwork::getConfig(unsigned char* config) const
|
||||
unsigned int CMMDVMNetwork::getShortConfig(unsigned char* config) const
|
||||
{
|
||||
if (m_configData == 0U)
|
||||
return 0U;
|
||||
@@ -248,39 +237,15 @@ bool CMMDVMNetwork::readTalkerAlias(unsigned char* data, unsigned int& length)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::readHomePosition(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_homePositionLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_homePositionData, m_homePositionLen);
|
||||
length = m_homePositionLen;
|
||||
|
||||
m_homePositionLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::writeBeacon()
|
||||
{
|
||||
unsigned char buffer[20U];
|
||||
::memcpy(buffer + 0U, "RPTSBKN", 7U);
|
||||
::memcpy(buffer + 7U, m_netId, 4U);
|
||||
|
||||
return m_socket.write(buffer, 11U, m_rptAddress, m_rptPort);
|
||||
return m_socket.write((unsigned char*)"DMRB", 4U, m_rptAddress, m_rptPort);
|
||||
}
|
||||
|
||||
void CMMDVMNetwork::close()
|
||||
{
|
||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
LogMessage("MMDVM Network, Closing");
|
||||
|
||||
::memcpy(buffer + 0U, "MSTCL", 5U);
|
||||
::memcpy(buffer + 5U, m_netId, 4U);
|
||||
|
||||
m_socket.write(buffer, HOMEBREW_DATA_PACKET_LENGTH, m_rptAddress, m_rptPort);
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
@@ -289,21 +254,18 @@ void CMMDVMNetwork::clock(unsigned int ms)
|
||||
in_addr address;
|
||||
unsigned int port;
|
||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port);
|
||||
if (length < 0) {
|
||||
LogError("MMDVM Network, Socket has failed, reopening");
|
||||
close();
|
||||
open();
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (m_rptAddress.s_addr != address.s_addr || m_rptPort != port) {
|
||||
LogMessage("Packet received from an invalid source, %08X != %08X and/or %u != %u", m_rptAddress.s_addr, address.s_addr, m_rptPort, port);
|
||||
return;
|
||||
}
|
||||
|
||||
// if (m_debug && length > 0)
|
||||
// CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||
|
||||
if (length > 0 && m_rptAddress.s_addr == address.s_addr && m_rptPort == port) {
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||
unsigned char len = length;
|
||||
m_rxData.addData(&len, 1U);
|
||||
m_rxData.addData(m_buffer, len);
|
||||
@@ -313,50 +275,15 @@ void CMMDVMNetwork::clock(unsigned int ms)
|
||||
} else if (::memcmp(m_buffer, "DMRA", 4U) == 0) {
|
||||
::memcpy(m_talkerAliasData, m_buffer, length);
|
||||
m_talkerAliasLen = length;
|
||||
} else if (::memcmp(m_buffer, "RPTG", 4U) == 0) {
|
||||
::memcpy(m_homePositionData, m_buffer, length);
|
||||
m_homePositionLen = length;
|
||||
} else if (::memcmp(m_buffer, "RPTL", 4U) == 0) {
|
||||
} else if (::memcmp(m_buffer, "DMRC", 4U) == 0) {
|
||||
m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
::memcpy(m_netId, m_buffer + 4U, 4U);
|
||||
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
|
||||
uint32_t salt = 1U;
|
||||
::memcpy(ack + 6U, &salt, sizeof(uint32_t));
|
||||
|
||||
m_socket.write(ack, 10U, m_rptAddress, m_rptPort);
|
||||
} else if (::memcmp(m_buffer, "RPTK", 4U) == 0) {
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
::memcpy(ack + 6U, m_netId, 4U);
|
||||
m_socket.write(ack, 10U, m_rptAddress, m_rptPort);
|
||||
} else if (::memcmp(m_buffer, "RPTCL", 5U) == 0) {
|
||||
::LogMessage("MMDVM Network, The connected MMDVM is closing down");
|
||||
} else if (::memcmp(m_buffer, "RPTC", 4U) == 0) {
|
||||
m_configLen = length - 8U;
|
||||
m_configData = new unsigned char[m_configLen];
|
||||
::memcpy(m_configData, m_buffer + 8U, m_configLen);
|
||||
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
::memcpy(ack + 6U, m_netId, 4U);
|
||||
m_socket.write(ack, 10U, m_rptAddress, m_rptPort);
|
||||
} else if (::memcmp(m_buffer, "RPTO", 4U) == 0) {
|
||||
m_options = std::string((char*)(m_buffer + 8U), length - 8U);
|
||||
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
::memcpy(ack + 6U, m_netId, 4U);
|
||||
m_socket.write(ack, 10U, m_rptAddress, m_rptPort);
|
||||
} else if (::memcmp(m_buffer, "RPTPING", 7U) == 0) {
|
||||
unsigned char pong[11U];
|
||||
::memcpy(pong + 0U, "MSTPONG", 7U);
|
||||
::memcpy(pong + 7U, m_netId, 4U);
|
||||
m_socket.write(pong, 11U, m_rptAddress, m_rptPort);
|
||||
m_socket.write((unsigned char*)"DMRP", 4U, m_rptAddress, m_rptPort);
|
||||
} else {
|
||||
CUtils::dump("Unknown packet from the master", m_buffer, length);
|
||||
}
|
||||
CUtils::dump("Unknown packet from the MMDVM", m_buffer, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,7 +19,6 @@
|
||||
#if !defined(MMDVMNetwork_H)
|
||||
#define MMDVMNetwork_H
|
||||
|
||||
#include "RepeaterProtocol.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
#include "RingBuffer.h"
|
||||
@@ -28,35 +27,31 @@
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
class CMMDVMNetwork : public IRepeaterProtocol
|
||||
class CMMDVMNetwork
|
||||
{
|
||||
public:
|
||||
CMMDVMNetwork(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug);
|
||||
virtual ~CMMDVMNetwork();
|
||||
~CMMDVMNetwork();
|
||||
|
||||
virtual std::string getOptions() const;
|
||||
unsigned int getShortConfig(unsigned char* config) const;
|
||||
|
||||
virtual unsigned int getConfig(unsigned char* config) const;
|
||||
unsigned int getId() const;
|
||||
|
||||
virtual unsigned int getId() const;
|
||||
bool open();
|
||||
|
||||
virtual bool open();
|
||||
bool read(CDMRData& data);
|
||||
|
||||
virtual bool read(CDMRData& data);
|
||||
bool write(const CDMRData& data);
|
||||
|
||||
virtual bool write(const CDMRData& data);
|
||||
bool readRadioPosition(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool readRadioPosition(unsigned char* data, unsigned int& length);
|
||||
bool readTalkerAlias(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool readTalkerAlias(unsigned char* data, unsigned int& length);
|
||||
bool writeBeacon();
|
||||
|
||||
virtual bool readHomePosition(unsigned char* data, unsigned int& length);
|
||||
void clock(unsigned int ms);
|
||||
|
||||
virtual bool writeBeacon();
|
||||
|
||||
virtual void clock(unsigned int ms);
|
||||
|
||||
virtual void close();
|
||||
void close();
|
||||
|
||||
private:
|
||||
in_addr m_rptAddress;
|
||||
@@ -67,15 +62,12 @@ private:
|
||||
CUDPSocket m_socket;
|
||||
unsigned char* m_buffer;
|
||||
CRingBuffer<unsigned char> m_rxData;
|
||||
std::string m_options;
|
||||
unsigned char* m_configData;
|
||||
unsigned int m_configLen;
|
||||
unsigned char* m_radioPositionData;
|
||||
unsigned int m_radioPositionLen;
|
||||
unsigned char* m_talkerAliasData;
|
||||
unsigned int m_talkerAliasLen;
|
||||
unsigned char* m_homePositionData;
|
||||
unsigned int m_homePositionLen;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
13
Makefile
13
Makefile
@@ -1,13 +1,20 @@
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
|
||||
# Use the following CFLAGS and LIBS if you don't want to use gpsd.
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
||||
LIBS = -lpthread
|
||||
|
||||
# Use the following CFLAGS and LIBS if you do want to use gpsd.
|
||||
#CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread
|
||||
#LIBS = -lpthread -lgps
|
||||
|
||||
LDFLAGS = -g
|
||||
|
||||
OBJECTS = BPTC19696.o Conf.o CRC.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREmbeddedData.o DMREMB.o DMRFullLC.o DMRGateway.o DMRLC.o DMRNetwork.o DMRSlotType.o \
|
||||
DynVoice.o Golay2087.o Hamming.o Log.o MMDVMNetwork.o PassAllPC.o PassAllTG.o QR1676.o Reflectors.o RepeaterProtocol.o Rewrite.o RewriteDstId.o \
|
||||
RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o \
|
||||
Timer.o UDPSocket.o Utils.o XLXVoice.o
|
||||
DynVoice.o Golay2087.o GPSD.o Hamming.o Log.o MMDVMNetwork.o PassAllPC.o PassAllTG.o QR1676.o Reflectors.o Rewrite.o \
|
||||
RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o \
|
||||
Thread.o Timer.o UDPSocket.o Utils.o XLXVoice.o
|
||||
|
||||
all: DMRGateway
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "RepeaterProtocol.h"
|
||||
|
||||
IRepeaterProtocol::~IRepeaterProtocol()
|
||||
{
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(RepeaterProtocol_H)
|
||||
#define RepeaterProtocol_H
|
||||
|
||||
#include "DMRData.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class IRepeaterProtocol {
|
||||
public:
|
||||
virtual ~IRepeaterProtocol() = 0;
|
||||
|
||||
virtual std::string getOptions() const = 0;
|
||||
|
||||
virtual unsigned int getConfig(unsigned char* config) const = 0;
|
||||
|
||||
virtual unsigned int getId() const = 0;
|
||||
|
||||
virtual bool open() = 0;
|
||||
|
||||
virtual bool read(CDMRData& data) = 0;
|
||||
|
||||
virtual bool write(const CDMRData& data) = 0;
|
||||
|
||||
virtual bool readRadioPosition(unsigned char* data, unsigned int& length) = 0;
|
||||
|
||||
virtual bool readTalkerAlias(unsigned char* data, unsigned int& length) = 0;
|
||||
|
||||
virtual bool readHomePosition(unsigned char* data, unsigned int& length) = 0;
|
||||
|
||||
virtual void clock(unsigned int ms) = 0;
|
||||
|
||||
virtual bool writeBeacon() = 0;
|
||||
|
||||
virtual void close() = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -75,9 +75,9 @@ PROCESS_RESULT CRewriteType::process(CDMRData& data, bool trace)
|
||||
else
|
||||
LogDebug("Rule Trace,\tRewriteType from \"%s\" Slot=%u Dst=TG%u-%u: not matched", m_name.c_str(), m_fromSlot, m_fromTGStart, m_fromTGEnd);
|
||||
if (m_toIdStart == m_toIdEnd)
|
||||
LogDebug("Rule Trace,\tRewriteType to \"\%s\" Slot=%u Dst=%u: matched", m_name.c_str(), m_toSlot, m_toIdStart);
|
||||
LogDebug("Rule Trace,\tRewriteType to \"%s\" Slot=%u Dst=%u: matched", m_name.c_str(), m_toSlot, m_toIdStart);
|
||||
else
|
||||
LogDebug("Rule Trace,\tRewriteType to \"\%s\" Slot=%u Dst=%u-%u: matched", m_name.c_str(), m_toSlot, m_toIdStart, m_toIdEnd);
|
||||
LogDebug("Rule Trace,\tRewriteType to \"%s\" Slot=%u Dst=%u-%u: matched", m_name.c_str(), m_toSlot, m_toIdStart, m_toIdEnd);
|
||||
}
|
||||
|
||||
return RESULT_MATCHED;
|
||||
|
||||
Reference in New Issue
Block a user