mirror of
https://github.com/g4klx/DMRGateway
synced 2026-02-05 05:45:43 +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_4,
|
||||||
SECTION_DMR_NETWORK_5,
|
SECTION_DMR_NETWORK_5,
|
||||||
SECTION_XLX_NETWORK,
|
SECTION_XLX_NETWORK,
|
||||||
SECTION_DYNAMIC_TG_CONTROL
|
SECTION_DYNAMIC_TG_CONTROL,
|
||||||
|
SECTION_GPSD,
|
||||||
};
|
};
|
||||||
|
|
||||||
CConf::CConf(const std::string& file) :
|
CConf::CConf(const std::string& file) :
|
||||||
@@ -59,14 +60,9 @@ m_logDisplayLevel(0U),
|
|||||||
m_logFileLevel(0U),
|
m_logFileLevel(0U),
|
||||||
m_logFilePath(),
|
m_logFilePath(),
|
||||||
m_logFileRoot(),
|
m_logFileRoot(),
|
||||||
m_infoEnabled(false),
|
|
||||||
m_infoRXFrequency(0U),
|
|
||||||
m_infoTXFrequency(0U),
|
|
||||||
m_infoPower(0U),
|
|
||||||
m_infoLatitude(0.0F),
|
m_infoLatitude(0.0F),
|
||||||
m_infoLongitude(0.0F),
|
m_infoLongitude(0.0F),
|
||||||
m_infoHeight(0),
|
m_infoHeight(0),
|
||||||
m_infoLocation(),
|
|
||||||
m_infoDescription(),
|
m_infoDescription(),
|
||||||
m_infoURL(),
|
m_infoURL(),
|
||||||
m_dmrNetwork1Enabled(false),
|
m_dmrNetwork1Enabled(false),
|
||||||
@@ -175,7 +171,10 @@ m_xlxNetworkDebug(false),
|
|||||||
m_xlxNetworkUserControl(true),
|
m_xlxNetworkUserControl(true),
|
||||||
m_xlxNetworkModule(),
|
m_xlxNetworkModule(),
|
||||||
m_dynamicTGControlEnabled(false),
|
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;
|
section = SECTION_DMR_NETWORK_5;
|
||||||
else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0)
|
else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0)
|
||||||
section = SECTION_DYNAMIC_TG_CONTROL;
|
section = SECTION_DYNAMIC_TG_CONTROL;
|
||||||
|
else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
||||||
|
section = SECTION_GPSD;
|
||||||
else
|
else
|
||||||
section = SECTION_NONE;
|
section = SECTION_NONE;
|
||||||
|
|
||||||
@@ -280,22 +281,12 @@ bool CConf::read()
|
|||||||
else if (::strcmp(key, "Directory") == 0)
|
else if (::strcmp(key, "Directory") == 0)
|
||||||
m_voiceDirectory = value;
|
m_voiceDirectory = value;
|
||||||
} else if (section == SECTION_INFO) {
|
} else if (section == SECTION_INFO) {
|
||||||
if (::strcmp(key, "Enabled") == 0)
|
if (::strcmp(key, "Latitude") == 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)
|
|
||||||
m_infoLatitude = float(::atof(value));
|
m_infoLatitude = float(::atof(value));
|
||||||
else if (::strcmp(key, "Longitude") == 0)
|
else if (::strcmp(key, "Longitude") == 0)
|
||||||
m_infoLongitude = float(::atof(value));
|
m_infoLongitude = float(::atof(value));
|
||||||
else if (::strcmp(key, "Height") == 0)
|
else if (::strcmp(key, "Height") == 0)
|
||||||
m_infoHeight = ::atoi(value);
|
m_infoHeight = ::atoi(value);
|
||||||
else if (::strcmp(key, "Location") == 0)
|
|
||||||
m_infoLocation = value;
|
|
||||||
else if (::strcmp(key, "Description") == 0)
|
else if (::strcmp(key, "Description") == 0)
|
||||||
m_infoDescription = value;
|
m_infoDescription = value;
|
||||||
else if (::strcmp(key, "URL") == 0)
|
else if (::strcmp(key, "URL") == 0)
|
||||||
@@ -946,6 +937,13 @@ bool CConf::read()
|
|||||||
m_dynamicTGControlEnabled = ::atoi(value) == 1;
|
m_dynamicTGControlEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Port") == 0)
|
else if (::strcmp(key, "Port") == 0)
|
||||||
m_dynamicTGControlPort = (unsigned int)::atoi(value);
|
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;
|
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
|
float CConf::getInfoLatitude() const
|
||||||
{
|
{
|
||||||
return m_infoLatitude;
|
return m_infoLatitude;
|
||||||
@@ -1069,11 +1047,6 @@ int CConf::getInfoHeight() const
|
|||||||
return m_infoHeight;
|
return m_infoHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CConf::getInfoLocation() const
|
|
||||||
{
|
|
||||||
return m_infoLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CConf::getInfoDescription() const
|
std::string CConf::getInfoDescription() const
|
||||||
{
|
{
|
||||||
return m_infoDescription;
|
return m_infoDescription;
|
||||||
@@ -1631,3 +1604,18 @@ unsigned int CConf::getDynamicTGControlPort() const
|
|||||||
{
|
{
|
||||||
return m_dynamicTGControlPort;
|
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;
|
std::string getVoiceDirectory() const;
|
||||||
|
|
||||||
// The Info section
|
// The Info section
|
||||||
bool getInfoEnabled() const;
|
|
||||||
unsigned int getInfoRXFrequency() const;
|
|
||||||
unsigned int getInfoTXFrequency() const;
|
|
||||||
unsigned int getInfoPower() const;
|
|
||||||
float getInfoLatitude() const;
|
float getInfoLatitude() const;
|
||||||
float getInfoLongitude() const;
|
float getInfoLongitude() const;
|
||||||
int getInfoHeight() const;
|
int getInfoHeight() const;
|
||||||
std::string getInfoLocation() const;
|
|
||||||
std::string getInfoDescription() const;
|
std::string getInfoDescription() const;
|
||||||
std::string getInfoURL() const;
|
std::string getInfoURL() const;
|
||||||
|
|
||||||
@@ -232,6 +227,11 @@ public:
|
|||||||
bool getDynamicTGControlEnabled() const;
|
bool getDynamicTGControlEnabled() const;
|
||||||
unsigned int getDynamicTGControlPort() const;
|
unsigned int getDynamicTGControlPort() const;
|
||||||
|
|
||||||
|
// The GPSD section
|
||||||
|
bool getGPSDEnabled() const;
|
||||||
|
std::string getGPSDAddress() const;
|
||||||
|
std::string getGPSDPort() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_file;
|
std::string m_file;
|
||||||
bool m_daemon;
|
bool m_daemon;
|
||||||
@@ -253,14 +253,9 @@ private:
|
|||||||
std::string m_logFilePath;
|
std::string m_logFilePath;
|
||||||
std::string m_logFileRoot;
|
std::string m_logFileRoot;
|
||||||
|
|
||||||
bool m_infoEnabled;
|
|
||||||
unsigned int m_infoRXFrequency;
|
|
||||||
unsigned int m_infoTXFrequency;
|
|
||||||
unsigned int m_infoPower;
|
|
||||||
float m_infoLatitude;
|
float m_infoLatitude;
|
||||||
float m_infoLongitude;
|
float m_infoLongitude;
|
||||||
int m_infoHeight;
|
int m_infoHeight;
|
||||||
std::string m_infoLocation;
|
|
||||||
std::string m_infoDescription;
|
std::string m_infoDescription;
|
||||||
std::string m_infoURL;
|
std::string m_infoURL;
|
||||||
|
|
||||||
@@ -377,6 +372,10 @@ private:
|
|||||||
|
|
||||||
bool m_dynamicTGControlEnabled;
|
bool m_dynamicTGControlEnabled;
|
||||||
unsigned int m_dynamicTGControlPort;
|
unsigned int m_dynamicTGControlPort;
|
||||||
|
|
||||||
|
bool m_gpsdEnabled;
|
||||||
|
std::string m_gpsdAddress;
|
||||||
|
std::string m_gpsdPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
160
DMRGateway.cpp
160
DMRGateway.cpp
@@ -182,6 +182,9 @@ m_dmr5Passalls(),
|
|||||||
m_dynVoices(),
|
m_dynVoices(),
|
||||||
m_dynRF(),
|
m_dynRF(),
|
||||||
m_socket(NULL)
|
m_socket(NULL)
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
,m_gpsd(NULL)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
m_status = new DMRGW_STATUS[3U];
|
m_status = new DMRGW_STATUS[3U];
|
||||||
m_status[1U] = DMRGWS_NONE;
|
m_status[1U] = DMRGWS_NONE;
|
||||||
@@ -354,7 +357,7 @@ int CDMRGateway::run()
|
|||||||
LogMessage("Waiting for MMDVM to connect.....");
|
LogMessage("Waiting for MMDVM to connect.....");
|
||||||
|
|
||||||
while (!m_killed) {
|
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)
|
if (m_configLen > 0U && m_repeater->getId() > 1000U)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -371,6 +374,26 @@ int CDMRGateway::run()
|
|||||||
|
|
||||||
LogMessage("MMDVM has connected");
|
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();
|
bool ruleTrace = m_conf.getRuleTrace();
|
||||||
LogInfo("Rule trace: %s", ruleTrace ? "yes" : "no");
|
LogInfo("Rule trace: %s", ruleTrace ? "yes" : "no");
|
||||||
|
|
||||||
@@ -1131,8 +1154,6 @@ int CDMRGateway::run()
|
|||||||
|
|
||||||
processTalkerAlias();
|
processTalkerAlias();
|
||||||
|
|
||||||
processHomePosition();
|
|
||||||
|
|
||||||
if (xlxVoice != NULL) {
|
if (xlxVoice != NULL) {
|
||||||
ret = xlxVoice->read(data);
|
ret = xlxVoice->read(data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -1183,6 +1204,11 @@ int CDMRGateway::run()
|
|||||||
if (xlxVoice != NULL)
|
if (xlxVoice != NULL)
|
||||||
xlxVoice->clock(ms);
|
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)
|
for (std::vector<CDynVoice*>::iterator it = m_dynVoices.begin(); it != m_dynVoices.end(); ++it)
|
||||||
(*it)->clock(ms);
|
(*it)->clock(ms);
|
||||||
|
|
||||||
@@ -1203,6 +1229,13 @@ int CDMRGateway::run()
|
|||||||
m_repeater->close();
|
m_repeater->close();
|
||||||
delete m_repeater;
|
delete m_repeater;
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (m_gpsd != NULL) {
|
||||||
|
m_gpsd->close();
|
||||||
|
delete m_gpsd;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_dmrNetwork1 != NULL) {
|
if (m_dmrNetwork1 != NULL) {
|
||||||
m_dmrNetwork1->close();
|
m_dmrNetwork1->close();
|
||||||
delete m_dmrNetwork1;
|
delete m_dmrNetwork1;
|
||||||
@@ -1297,11 +1330,9 @@ bool CDMRGateway::createDMRNetwork1()
|
|||||||
LogInfo(" Local: random");
|
LogInfo(" Local: random");
|
||||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
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();
|
std::string options = m_conf.getDMRNetwork1Options();
|
||||||
if (options.empty())
|
|
||||||
options = m_repeater->getOptions();
|
|
||||||
|
|
||||||
if (!options.empty()) {
|
if (!options.empty()) {
|
||||||
LogInfo(" Options: %s", options.c_str());
|
LogInfo(" Options: %s", options.c_str());
|
||||||
@@ -1310,10 +1341,6 @@ bool CDMRGateway::createDMRNetwork1()
|
|||||||
|
|
||||||
unsigned char config[400U];
|
unsigned char config[400U];
|
||||||
unsigned int len = getConfig(m_dmr1Name, config);
|
unsigned int len = getConfig(m_dmr1Name, config);
|
||||||
|
|
||||||
if (!location)
|
|
||||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
||||||
|
|
||||||
m_dmrNetwork1->setConfig(config, len);
|
m_dmrNetwork1->setConfig(config, len);
|
||||||
|
|
||||||
bool ret = m_dmrNetwork1->open();
|
bool ret = m_dmrNetwork1->open();
|
||||||
@@ -1323,6 +1350,11 @@ bool CDMRGateway::createDMRNetwork1()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (location)
|
||||||
|
m_gpsd->addNetwork(m_dmrNetwork1);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork1TGRewrites();
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork1TGRewrites();
|
||||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||||
if ((*it).m_range == 1)
|
if ((*it).m_range == 1)
|
||||||
@@ -1465,11 +1497,9 @@ bool CDMRGateway::createDMRNetwork2()
|
|||||||
LogInfo(" Local: random");
|
LogInfo(" Local: random");
|
||||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
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();
|
std::string options = m_conf.getDMRNetwork2Options();
|
||||||
if (options.empty())
|
|
||||||
options = m_repeater->getOptions();
|
|
||||||
|
|
||||||
if (!options.empty()) {
|
if (!options.empty()) {
|
||||||
LogInfo(" Options: %s", options.c_str());
|
LogInfo(" Options: %s", options.c_str());
|
||||||
@@ -1479,9 +1509,6 @@ bool CDMRGateway::createDMRNetwork2()
|
|||||||
unsigned char config[400U];
|
unsigned char config[400U];
|
||||||
unsigned int len = getConfig(m_dmr2Name, config);
|
unsigned int len = getConfig(m_dmr2Name, config);
|
||||||
|
|
||||||
if (!location)
|
|
||||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
||||||
|
|
||||||
m_dmrNetwork2->setConfig(config, len);
|
m_dmrNetwork2->setConfig(config, len);
|
||||||
|
|
||||||
bool ret = m_dmrNetwork2->open();
|
bool ret = m_dmrNetwork2->open();
|
||||||
@@ -1491,6 +1518,11 @@ bool CDMRGateway::createDMRNetwork2()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (location)
|
||||||
|
m_gpsd->addNetwork(m_dmrNetwork2);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork2TGRewrites();
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork2TGRewrites();
|
||||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||||
if ((*it).m_range == 1)
|
if ((*it).m_range == 1)
|
||||||
@@ -1633,11 +1665,9 @@ bool CDMRGateway::createDMRNetwork3()
|
|||||||
LogInfo(" Local: random");
|
LogInfo(" Local: random");
|
||||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
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();
|
std::string options = m_conf.getDMRNetwork3Options();
|
||||||
if (options.empty())
|
|
||||||
options = m_repeater->getOptions();
|
|
||||||
|
|
||||||
if (!options.empty()) {
|
if (!options.empty()) {
|
||||||
LogInfo(" Options: %s", options.c_str());
|
LogInfo(" Options: %s", options.c_str());
|
||||||
@@ -1646,10 +1676,6 @@ bool CDMRGateway::createDMRNetwork3()
|
|||||||
|
|
||||||
unsigned char config[400U];
|
unsigned char config[400U];
|
||||||
unsigned int len = getConfig(m_dmr3Name, config);
|
unsigned int len = getConfig(m_dmr3Name, config);
|
||||||
|
|
||||||
if (!location)
|
|
||||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
||||||
|
|
||||||
m_dmrNetwork3->setConfig(config, len);
|
m_dmrNetwork3->setConfig(config, len);
|
||||||
|
|
||||||
bool ret = m_dmrNetwork3->open();
|
bool ret = m_dmrNetwork3->open();
|
||||||
@@ -1659,6 +1685,11 @@ bool CDMRGateway::createDMRNetwork3()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (location)
|
||||||
|
m_gpsd->addNetwork(m_dmrNetwork3);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork3TGRewrites();
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork3TGRewrites();
|
||||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||||
if ((*it).m_range == 1)
|
if ((*it).m_range == 1)
|
||||||
@@ -1801,11 +1832,9 @@ bool CDMRGateway::createDMRNetwork4()
|
|||||||
LogInfo(" Local: random");
|
LogInfo(" Local: random");
|
||||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
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();
|
std::string options = m_conf.getDMRNetwork4Options();
|
||||||
if (options.empty())
|
|
||||||
options = m_repeater->getOptions();
|
|
||||||
|
|
||||||
if (!options.empty()) {
|
if (!options.empty()) {
|
||||||
LogInfo(" Options: %s", options.c_str());
|
LogInfo(" Options: %s", options.c_str());
|
||||||
@@ -1814,10 +1843,6 @@ bool CDMRGateway::createDMRNetwork4()
|
|||||||
|
|
||||||
unsigned char config[400U];
|
unsigned char config[400U];
|
||||||
unsigned int len = getConfig(m_dmr4Name, config);
|
unsigned int len = getConfig(m_dmr4Name, config);
|
||||||
|
|
||||||
if (!location)
|
|
||||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
||||||
|
|
||||||
m_dmrNetwork4->setConfig(config, len);
|
m_dmrNetwork4->setConfig(config, len);
|
||||||
|
|
||||||
bool ret = m_dmrNetwork4->open();
|
bool ret = m_dmrNetwork4->open();
|
||||||
@@ -1827,6 +1852,11 @@ bool CDMRGateway::createDMRNetwork4()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (location)
|
||||||
|
m_gpsd->addNetwork(m_dmrNetwork4);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork4TGRewrites();
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork4TGRewrites();
|
||||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||||
if ((*it).m_range == 1)
|
if ((*it).m_range == 1)
|
||||||
@@ -1969,11 +1999,9 @@ bool CDMRGateway::createDMRNetwork5()
|
|||||||
LogInfo(" Local: random");
|
LogInfo(" Local: random");
|
||||||
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
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();
|
std::string options = m_conf.getDMRNetwork5Options();
|
||||||
if (options.empty())
|
|
||||||
options = m_repeater->getOptions();
|
|
||||||
|
|
||||||
if (!options.empty()) {
|
if (!options.empty()) {
|
||||||
LogInfo(" Options: %s", options.c_str());
|
LogInfo(" Options: %s", options.c_str());
|
||||||
@@ -1982,10 +2010,6 @@ bool CDMRGateway::createDMRNetwork5()
|
|||||||
|
|
||||||
unsigned char config[400U];
|
unsigned char config[400U];
|
||||||
unsigned int len = getConfig(m_dmr5Name, config);
|
unsigned int len = getConfig(m_dmr5Name, config);
|
||||||
|
|
||||||
if (!location)
|
|
||||||
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
||||||
|
|
||||||
m_dmrNetwork5->setConfig(config, len);
|
m_dmrNetwork5->setConfig(config, len);
|
||||||
|
|
||||||
bool ret = m_dmrNetwork5->open();
|
bool ret = m_dmrNetwork5->open();
|
||||||
@@ -1995,6 +2019,11 @@ bool CDMRGateway::createDMRNetwork5()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (location)
|
||||||
|
m_gpsd->addNetwork(m_dmrNetwork5);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork5TGRewrites();
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork5TGRewrites();
|
||||||
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
||||||
if ((*it).m_range == 1)
|
if ((*it).m_range == 1)
|
||||||
@@ -2213,7 +2242,7 @@ bool CDMRGateway::linkXLX(unsigned int number)
|
|||||||
m_xlxConnected = false;
|
m_xlxConnected = false;
|
||||||
m_xlxRelink.stop();
|
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 char config[400U];
|
||||||
unsigned int len = getConfig("XLX", config);
|
unsigned int len = getConfig("XLX", config);
|
||||||
@@ -2319,16 +2348,6 @@ unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buff
|
|||||||
{
|
{
|
||||||
assert(buffer != NULL);
|
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];
|
char latitude[20U];
|
||||||
float lat = m_conf.getInfoLatitude();
|
float lat = m_conf.getInfoLatitude();
|
||||||
::sprintf(latitude, "%08f", lat);
|
::sprintf(latitude, "%08f", lat);
|
||||||
@@ -2337,25 +2356,18 @@ unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buff
|
|||||||
float lon = m_conf.getInfoLongitude();
|
float lon = m_conf.getInfoLongitude();
|
||||||
::sprintf(longitude, "%09f", lon);
|
::sprintf(longitude, "%09f", lon);
|
||||||
|
|
||||||
unsigned int power = m_conf.getInfoPower();
|
|
||||||
if (power > 99U)
|
|
||||||
power = 99U;
|
|
||||||
|
|
||||||
int height = m_conf.getInfoHeight();
|
int height = m_conf.getInfoHeight();
|
||||||
if (height > 999)
|
if (height > 999)
|
||||||
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 description = m_conf.getInfoDescription();
|
||||||
std::string url = m_conf.getInfoURL();
|
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,
|
::sprintf((char*)buffer, "%30.30s%9.9s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%80.80s",
|
||||||
rxFrequency, txFrequency, power, m_config + 28U, latitude, longitude, height, location.c_str(),
|
m_config + 0U, latitude, longitude, height, m_config + 30U,
|
||||||
description.c_str(), m_config[89U], url.c_str(), m_config + 214U, m_config + 254U);
|
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);
|
return (unsigned int)::strlen((char*)buffer);
|
||||||
}
|
}
|
||||||
@@ -2368,9 +2380,6 @@ void CDMRGateway::processRadioPosition()
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
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))
|
if (m_dmrNetwork1 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1))
|
||||||
m_dmrNetwork1->writeRadioPosition(buffer, length);
|
m_dmrNetwork1->writeRadioPosition(buffer, length);
|
||||||
|
|
||||||
@@ -2414,33 +2423,6 @@ void CDMRGateway::processTalkerAlias()
|
|||||||
m_dmrNetwork5->writeTalkerAlias(buffer, length);
|
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()
|
void CDMRGateway::processDynamicTGControl()
|
||||||
{
|
{
|
||||||
unsigned char buffer[100U];
|
unsigned char buffer[100U];
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#if !defined(DMRGateway_H)
|
#if !defined(DMRGateway_H)
|
||||||
#define DMRGateway_H
|
#define DMRGateway_H
|
||||||
|
|
||||||
#include "RepeaterProtocol.h"
|
|
||||||
#include "RewriteDynTGNet.h"
|
#include "RewriteDynTGNet.h"
|
||||||
#include "RewriteDynTGRF.h"
|
#include "RewriteDynTGRF.h"
|
||||||
#include "MMDVMNetwork.h"
|
#include "MMDVMNetwork.h"
|
||||||
@@ -31,6 +30,7 @@
|
|||||||
#include "Rewrite.h"
|
#include "Rewrite.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
||||||
|
#include "GPSD.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
CConf m_conf;
|
CConf m_conf;
|
||||||
DMRGW_STATUS* m_status;
|
DMRGW_STATUS* m_status;
|
||||||
IRepeaterProtocol* m_repeater;
|
CMMDVMNetwork* m_repeater;
|
||||||
unsigned char* m_config;
|
unsigned char* m_config;
|
||||||
unsigned int m_configLen;
|
unsigned int m_configLen;
|
||||||
CDMRNetwork* m_dmrNetwork1;
|
CDMRNetwork* m_dmrNetwork1;
|
||||||
@@ -111,6 +111,9 @@ private:
|
|||||||
std::vector<CDynVoice*> m_dynVoices;
|
std::vector<CDynVoice*> m_dynVoices;
|
||||||
std::vector<CRewriteDynTGRF*> m_dynRF;
|
std::vector<CRewriteDynTGRF*> m_dynRF;
|
||||||
CUDPSocket* m_socket;
|
CUDPSocket* m_socket;
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
CGPSD* m_gpsd;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool createMMDVM();
|
bool createMMDVM();
|
||||||
bool createDMRNetwork1();
|
bool createDMRNetwork1();
|
||||||
@@ -131,7 +134,6 @@ private:
|
|||||||
|
|
||||||
void processRadioPosition();
|
void processRadioPosition();
|
||||||
void processTalkerAlias();
|
void processTalkerAlias();
|
||||||
void processHomePosition();
|
|
||||||
void processDynamicTGControl();
|
void processDynamicTGControl();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,9 @@ Language=en_GB
|
|||||||
Directory=./Audio
|
Directory=./Audio
|
||||||
|
|
||||||
[Info]
|
[Info]
|
||||||
Enabled=0
|
|
||||||
RXFrequency=435000000
|
|
||||||
TXFrequency=435000000
|
|
||||||
Power=1
|
|
||||||
Latitude=0.0
|
Latitude=0.0
|
||||||
Longitude=0.0
|
Longitude=0.0
|
||||||
Height=0
|
Height=0
|
||||||
Location=Nowhere
|
|
||||||
Description=Multi-Mode Repeater
|
Description=Multi-Mode Repeater
|
||||||
URL=www.google.co.uk
|
URL=www.google.co.uk
|
||||||
|
|
||||||
@@ -137,6 +132,11 @@ Password=PASSWORD
|
|||||||
Location=0
|
Location=0
|
||||||
Debug=0
|
Debug=0
|
||||||
|
|
||||||
|
[GPSD]
|
||||||
|
Enable=0
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=2947
|
||||||
|
|
||||||
[Dynamic TG Control]
|
[Dynamic TG Control]
|
||||||
Enabled=1
|
Enabled=1
|
||||||
Port=3769
|
Port=3769
|
||||||
|
|||||||
@@ -168,6 +168,7 @@
|
|||||||
<ClInclude Include="DMRSlotType.h" />
|
<ClInclude Include="DMRSlotType.h" />
|
||||||
<ClInclude Include="DynVoice.h" />
|
<ClInclude Include="DynVoice.h" />
|
||||||
<ClInclude Include="Golay2087.h" />
|
<ClInclude Include="Golay2087.h" />
|
||||||
|
<ClInclude Include="GPSD.h" />
|
||||||
<ClInclude Include="Hamming.h" />
|
<ClInclude Include="Hamming.h" />
|
||||||
<ClInclude Include="Log.h" />
|
<ClInclude Include="Log.h" />
|
||||||
<ClInclude Include="MMDVMNetwork.h" />
|
<ClInclude Include="MMDVMNetwork.h" />
|
||||||
@@ -175,7 +176,6 @@
|
|||||||
<ClInclude Include="PassAllTG.h" />
|
<ClInclude Include="PassAllTG.h" />
|
||||||
<ClInclude Include="QR1676.h" />
|
<ClInclude Include="QR1676.h" />
|
||||||
<ClInclude Include="Reflectors.h" />
|
<ClInclude Include="Reflectors.h" />
|
||||||
<ClInclude Include="RepeaterProtocol.h" />
|
|
||||||
<ClInclude Include="Rewrite.h" />
|
<ClInclude Include="Rewrite.h" />
|
||||||
<ClInclude Include="RewriteDstId.h" />
|
<ClInclude Include="RewriteDstId.h" />
|
||||||
<ClInclude Include="RewriteDynTGNet.h" />
|
<ClInclude Include="RewriteDynTGNet.h" />
|
||||||
@@ -213,6 +213,7 @@
|
|||||||
<ClCompile Include="DMRSlotType.cpp" />
|
<ClCompile Include="DMRSlotType.cpp" />
|
||||||
<ClCompile Include="DynVoice.cpp" />
|
<ClCompile Include="DynVoice.cpp" />
|
||||||
<ClCompile Include="Golay2087.cpp" />
|
<ClCompile Include="Golay2087.cpp" />
|
||||||
|
<ClCompile Include="GPSD.cpp" />
|
||||||
<ClCompile Include="Hamming.cpp" />
|
<ClCompile Include="Hamming.cpp" />
|
||||||
<ClCompile Include="Log.cpp" />
|
<ClCompile Include="Log.cpp" />
|
||||||
<ClCompile Include="MMDVMNetwork.cpp" />
|
<ClCompile Include="MMDVMNetwork.cpp" />
|
||||||
@@ -220,7 +221,6 @@
|
|||||||
<ClCompile Include="PassAllTG.cpp" />
|
<ClCompile Include="PassAllTG.cpp" />
|
||||||
<ClCompile Include="QR1676.cpp" />
|
<ClCompile Include="QR1676.cpp" />
|
||||||
<ClCompile Include="Reflectors.cpp" />
|
<ClCompile Include="Reflectors.cpp" />
|
||||||
<ClCompile Include="RepeaterProtocol.cpp" />
|
|
||||||
<ClCompile Include="Rewrite.cpp" />
|
<ClCompile Include="Rewrite.cpp" />
|
||||||
<ClCompile Include="RewriteDstId.cpp" />
|
<ClCompile Include="RewriteDstId.cpp" />
|
||||||
<ClCompile Include="RewriteDynTGNet.cpp" />
|
<ClCompile Include="RewriteDynTGNet.cpp" />
|
||||||
|
|||||||
@@ -83,9 +83,6 @@
|
|||||||
<ClInclude Include="CRC.h">
|
<ClInclude Include="CRC.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="RepeaterProtocol.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMREMB.h">
|
<ClInclude Include="DMREMB.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -143,6 +140,9 @@
|
|||||||
<ClInclude Include="DynVoice.h">
|
<ClInclude Include="DynVoice.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="GPSD.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Conf.cpp">
|
<ClCompile Include="Conf.cpp">
|
||||||
@@ -208,9 +208,6 @@
|
|||||||
<ClCompile Include="CRC.cpp">
|
<ClCompile Include="CRC.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="RepeaterProtocol.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMREMB.cpp">
|
<ClCompile Include="DMREMB.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -268,5 +265,8 @@
|
|||||||
<ClCompile Include="DynVoice.cpp">
|
<ClCompile Include="DynVoice.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GPSD.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</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
|
* 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
|
* 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;
|
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_address(),
|
||||||
m_port(port),
|
m_port(port),
|
||||||
m_id(NULL),
|
m_id(NULL),
|
||||||
m_password(password),
|
m_password(password),
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_version(version),
|
m_version(version),
|
||||||
|
m_location(location),
|
||||||
m_debug(debug),
|
m_debug(debug),
|
||||||
m_socket(local),
|
m_socket(local),
|
||||||
m_status(WAITING_CONNECT),
|
m_status(WAITING_CONNECT),
|
||||||
@@ -233,13 +234,16 @@ bool CDMRNetwork::writeRadioPosition(const unsigned char* data, unsigned int len
|
|||||||
if (m_status != RUNNING)
|
if (m_status != RUNNING)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!m_location)
|
||||||
|
return false;
|
||||||
|
|
||||||
unsigned char buffer[50U];
|
unsigned char buffer[50U];
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "DMRG", 4U);
|
::memcpy(buffer + 0U, "DMRG", 4U);
|
||||||
|
|
||||||
::memcpy(buffer + 4U, m_id, 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);
|
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 + 4U, m_id, 4U);
|
||||||
|
|
||||||
::memcpy(buffer + 8U, data + 8U, length - 8U);
|
::memcpy(buffer + 8U, data + 4U, length - 4U);
|
||||||
|
|
||||||
return write(buffer, length);
|
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)
|
if (m_status != RUNNING)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char buffer[50U];
|
if (!m_location)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char buffer[50U];
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "RPTG", 4U);
|
::memcpy(buffer + 0U, "RPTG", 4U);
|
||||||
|
|
||||||
::memcpy(buffer + 4U, m_id, 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
|
bool CDMRNetwork::isConnected() const
|
||||||
@@ -497,6 +504,9 @@ bool CDMRNetwork::writeConfig()
|
|||||||
::memset(buffer + 222U, ' ', 40U);
|
::memset(buffer + 222U, ' ', 40U);
|
||||||
::memcpy(buffer + 222U, software, ::strlen(software));
|
::memcpy(buffer + 222U, software, ::strlen(software));
|
||||||
|
|
||||||
|
if (!m_location)
|
||||||
|
::memcpy(buffer + 30U, "0.00000000.000000", 17U);
|
||||||
|
|
||||||
return write((unsigned char*)buffer, m_configLen + 8U);
|
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
class CDMRNetwork
|
class CDMRNetwork
|
||||||
{
|
{
|
||||||
public:
|
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();
|
~CDMRNetwork();
|
||||||
|
|
||||||
void setOptions(const std::string& options);
|
void setOptions(const std::string& options);
|
||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
|
|
||||||
bool writeTalkerAlias(const unsigned char* data, unsigned int length);
|
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();
|
bool wantsBeacon();
|
||||||
|
|
||||||
@@ -64,6 +64,7 @@ private:
|
|||||||
std::string m_password;
|
std::string m_password;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
const char* m_version;
|
const char* m_version;
|
||||||
|
bool m_location;
|
||||||
bool m_debug;
|
bool m_debug;
|
||||||
CUDPSocket m_socket;
|
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "MMDVMNetwork.h"
|
#include "MMDVMNetwork.h"
|
||||||
|
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
#include "SHA256.h"
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@@ -40,15 +39,12 @@ m_debug(debug),
|
|||||||
m_socket(localAddress, localPort),
|
m_socket(localAddress, localPort),
|
||||||
m_buffer(NULL),
|
m_buffer(NULL),
|
||||||
m_rxData(1000U, "MMDVM Network"),
|
m_rxData(1000U, "MMDVM Network"),
|
||||||
m_options(),
|
|
||||||
m_configData(NULL),
|
m_configData(NULL),
|
||||||
m_configLen(0U),
|
m_configLen(0U),
|
||||||
m_radioPositionData(NULL),
|
m_radioPositionData(NULL),
|
||||||
m_radioPositionLen(0U),
|
m_radioPositionLen(0U),
|
||||||
m_talkerAliasData(NULL),
|
m_talkerAliasData(NULL),
|
||||||
m_talkerAliasLen(0U),
|
m_talkerAliasLen(0U)
|
||||||
m_homePositionData(NULL),
|
|
||||||
m_homePositionLen(0U)
|
|
||||||
{
|
{
|
||||||
assert(!rptAddress.empty());
|
assert(!rptAddress.empty());
|
||||||
assert(rptPort > 0U);
|
assert(rptPort > 0U);
|
||||||
@@ -60,7 +56,6 @@ m_homePositionLen(0U)
|
|||||||
|
|
||||||
m_radioPositionData = new unsigned char[50U];
|
m_radioPositionData = new unsigned char[50U];
|
||||||
m_talkerAliasData = new unsigned char[50U];
|
m_talkerAliasData = new unsigned char[50U];
|
||||||
m_homePositionData = new unsigned char[50U];
|
|
||||||
|
|
||||||
CStopWatch stopWatch;
|
CStopWatch stopWatch;
|
||||||
::srand(stopWatch.start());
|
::srand(stopWatch.start());
|
||||||
@@ -73,15 +68,9 @@ CMMDVMNetwork::~CMMDVMNetwork()
|
|||||||
delete[] m_configData;
|
delete[] m_configData;
|
||||||
delete[] m_radioPositionData;
|
delete[] m_radioPositionData;
|
||||||
delete[] m_talkerAliasData;
|
delete[] m_talkerAliasData;
|
||||||
delete[] m_homePositionData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CMMDVMNetwork::getOptions() const
|
unsigned int CMMDVMNetwork::getShortConfig(unsigned char* config) const
|
||||||
{
|
|
||||||
return m_options;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int CMMDVMNetwork::getConfig(unsigned char* config) const
|
|
||||||
{
|
{
|
||||||
if (m_configData == 0U)
|
if (m_configData == 0U)
|
||||||
return 0U;
|
return 0U;
|
||||||
@@ -248,39 +237,15 @@ bool CMMDVMNetwork::readTalkerAlias(unsigned char* data, unsigned int& length)
|
|||||||
return true;
|
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()
|
bool CMMDVMNetwork::writeBeacon()
|
||||||
{
|
{
|
||||||
unsigned char buffer[20U];
|
return m_socket.write((unsigned char*)"DMRB", 4U, m_rptAddress, m_rptPort);
|
||||||
::memcpy(buffer + 0U, "RPTSBKN", 7U);
|
|
||||||
::memcpy(buffer + 7U, m_netId, 4U);
|
|
||||||
|
|
||||||
return m_socket.write(buffer, 11U, m_rptAddress, m_rptPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMMDVMNetwork::close()
|
void CMMDVMNetwork::close()
|
||||||
{
|
{
|
||||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
|
||||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
|
||||||
|
|
||||||
LogMessage("MMDVM Network, Closing");
|
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();
|
m_socket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,21 +254,18 @@ void CMMDVMNetwork::clock(unsigned int ms)
|
|||||||
in_addr address;
|
in_addr address;
|
||||||
unsigned int port;
|
unsigned int port;
|
||||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port);
|
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port);
|
||||||
if (length < 0) {
|
if (length <= 0)
|
||||||
LogError("MMDVM Network, Socket has failed, reopening");
|
return;
|
||||||
close();
|
|
||||||
open();
|
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;
|
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)
|
if (m_debug)
|
||||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||||
|
|
||||||
|
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||||
unsigned char len = length;
|
unsigned char len = length;
|
||||||
m_rxData.addData(&len, 1U);
|
m_rxData.addData(&len, 1U);
|
||||||
m_rxData.addData(m_buffer, len);
|
m_rxData.addData(m_buffer, len);
|
||||||
@@ -313,50 +275,15 @@ void CMMDVMNetwork::clock(unsigned int ms)
|
|||||||
} else if (::memcmp(m_buffer, "DMRA", 4U) == 0) {
|
} else if (::memcmp(m_buffer, "DMRA", 4U) == 0) {
|
||||||
::memcpy(m_talkerAliasData, m_buffer, length);
|
::memcpy(m_talkerAliasData, m_buffer, length);
|
||||||
m_talkerAliasLen = length;
|
m_talkerAliasLen = length;
|
||||||
} else if (::memcmp(m_buffer, "RPTG", 4U) == 0) {
|
} else if (::memcmp(m_buffer, "DMRC", 4U) == 0) {
|
||||||
::memcpy(m_homePositionData, m_buffer, length);
|
|
||||||
m_homePositionLen = length;
|
|
||||||
} else if (::memcmp(m_buffer, "RPTL", 4U) == 0) {
|
|
||||||
m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 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_configLen = length - 8U;
|
||||||
m_configData = new unsigned char[m_configLen];
|
m_configData = new unsigned char[m_configLen];
|
||||||
::memcpy(m_configData, m_buffer + 8U, m_configLen);
|
::memcpy(m_configData, m_buffer + 8U, m_configLen);
|
||||||
|
|
||||||
unsigned char ack[10U];
|
m_socket.write((unsigned char*)"DMRP", 4U, m_rptAddress, m_rptPort);
|
||||||
::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);
|
|
||||||
} else {
|
} 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#if !defined(MMDVMNetwork_H)
|
#if !defined(MMDVMNetwork_H)
|
||||||
#define MMDVMNetwork_H
|
#define MMDVMNetwork_H
|
||||||
|
|
||||||
#include "RepeaterProtocol.h"
|
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "RingBuffer.h"
|
#include "RingBuffer.h"
|
||||||
@@ -28,35 +27,31 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
class CMMDVMNetwork : public IRepeaterProtocol
|
class CMMDVMNetwork
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMMDVMNetwork(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug);
|
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();
|
void close();
|
||||||
|
|
||||||
virtual void clock(unsigned int ms);
|
|
||||||
|
|
||||||
virtual void close();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
in_addr m_rptAddress;
|
in_addr m_rptAddress;
|
||||||
@@ -67,15 +62,12 @@ private:
|
|||||||
CUDPSocket m_socket;
|
CUDPSocket m_socket;
|
||||||
unsigned char* m_buffer;
|
unsigned char* m_buffer;
|
||||||
CRingBuffer<unsigned char> m_rxData;
|
CRingBuffer<unsigned char> m_rxData;
|
||||||
std::string m_options;
|
|
||||||
unsigned char* m_configData;
|
unsigned char* m_configData;
|
||||||
unsigned int m_configLen;
|
unsigned int m_configLen;
|
||||||
unsigned char* m_radioPositionData;
|
unsigned char* m_radioPositionData;
|
||||||
unsigned int m_radioPositionLen;
|
unsigned int m_radioPositionLen;
|
||||||
unsigned char* m_talkerAliasData;
|
unsigned char* m_talkerAliasData;
|
||||||
unsigned int m_talkerAliasLen;
|
unsigned int m_talkerAliasLen;
|
||||||
unsigned char* m_homePositionData;
|
|
||||||
unsigned int m_homePositionLen;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
13
Makefile
13
Makefile
@@ -1,13 +1,20 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CXX = g++
|
CXX = g++
|
||||||
|
|
||||||
|
# Use the following CFLAGS and LIBS if you don't want to use gpsd.
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
||||||
LIBS = -lpthread
|
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
|
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 \
|
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 \
|
DynVoice.o Golay2087.o GPSD.o Hamming.o Log.o MMDVMNetwork.o PassAllPC.o PassAllTG.o QR1676.o Reflectors.o Rewrite.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 \
|
RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o \
|
||||||
Timer.o UDPSocket.o Utils.o XLXVoice.o
|
Thread.o Timer.o UDPSocket.o Utils.o XLXVoice.o
|
||||||
|
|
||||||
all: DMRGateway
|
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
|
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);
|
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)
|
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
|
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;
|
return RESULT_MATCHED;
|
||||||
|
|||||||
Reference in New Issue
Block a user