diff --git a/Conf.cpp b/Conf.cpp
index 9325a1b..d857c53 100644
--- a/Conf.cpp
+++ b/Conf.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
+ * Copyright (C) 2015-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
@@ -44,6 +44,7 @@ enum SECTION {
SECTION_P25,
SECTION_NXDN,
SECTION_POCSAG,
+ SECTION_FM,
SECTION_DSTAR_NETWORK,
SECTION_DMR_NETWORK,
SECTION_FUSION_NETWORK,
@@ -170,6 +171,29 @@ m_nxdnRemoteGateway(false),
m_nxdnModeHang(10U),
m_pocsagEnabled(false),
m_pocsagFrequency(0U),
+m_fmEnabled(false),
+m_fmCallsign(),
+m_fmCallsignSpeed(20U),
+m_fmCallsignFrequency(1000U),
+m_fmCallsignTime(10U),
+m_fmCallsignHoldoff(1U),
+m_fmCallsignHighLevel(80U),
+m_fmCallsignLowLevel(40U),
+m_fmCallsignAtStart(true),
+m_fmCallsignAtEnd(true),
+m_fmAck("K"),
+m_fmAckSpeed(20U),
+m_fmAckFrequency(1750U),
+m_fmAckDelay(1000U),
+m_fmAckLevel(80U),
+m_fmTimeoutLevel(80U),
+m_fmCTCSSFrequency(88.6F),
+m_fmCTCSSThreshold(100U),
+m_fmCTCSSLevel(5U),
+m_fmInputLevel(50U),
+m_fmOutputLevel(50U),
+m_fmKerchunkTime(0U),
+m_fmHangTime(7U),
m_dstarNetworkEnabled(false),
m_dstarGatewayAddress(),
m_dstarGatewayPort(0U),
@@ -244,6 +268,7 @@ m_lcdprocPort(0U),
m_lcdprocLocalPort(0U),
m_lcdprocDisplayClock(false),
m_lcdprocUTC(false),
+m_lcdprocDimOnIdle(false),
m_lockFileEnabled(false),
m_lockFileName(),
m_mobileGPSEnabled(false),
@@ -304,6 +329,8 @@ bool CConf::read()
section = SECTION_NXDN;
else if (::strncmp(buffer, "[POCSAG]", 8U) == 0)
section = SECTION_POCSAG;
+ else if (::strncmp(buffer, "[FM]", 4U) == 0)
+ section = SECTION_FM;
else if (::strncmp(buffer, "[D-Star Network]", 16U) == 0)
section = SECTION_DSTAR_NETWORK;
else if (::strncmp(buffer, "[DMR Network]", 13U) == 0)
@@ -652,10 +679,57 @@ bool CConf::read()
else if (::strcmp(key, "ModeHang") == 0)
m_nxdnModeHang = (unsigned int)::atoi(value);
} else if (section == SECTION_POCSAG) {
+ if (::strcmp(key, "Enable") == 0)
+ m_pocsagEnabled = ::atoi(value) == 1;
+ else if (::strcmp(key, "Frequency") == 0)
+ m_pocsagFrequency = (unsigned int)::atoi(value);
+ } else if (section == SECTION_FM) {
if (::strcmp(key, "Enable") == 0)
- m_pocsagEnabled = ::atoi(value) == 1;
- else if (::strcmp(key, "Frequency") == 0)
- m_pocsagFrequency = (unsigned int)::atoi(value);
+ m_fmEnabled = ::atoi(value) == 1;
+ else if (::strcmp(key, "Callsign") == 0)
+ m_fmCallsign = value;
+ else if (::strcmp(key, "CallsignSpeed") == 0)
+ m_fmCallsignSpeed = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CallsignFrequency") == 0)
+ m_fmCallsignFrequency = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CallsignTime") == 0)
+ m_fmCallsignTime = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CallsignHoldoff") == 0)
+ m_fmCallsignHoldoff = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CallsignHighLevel") == 0)
+ m_fmCallsignHighLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CallsignLowLevel") == 0)
+ m_fmCallsignLowLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CallsignAtStart") == 0)
+ m_fmCallsignAtStart = ::atoi(value) == 1;
+ else if (::strcmp(key, "CallsignAtEnd") == 0)
+ m_fmCallsignAtEnd = ::atoi(value) == 1;
+ else if (::strcmp(key, "Ack") == 0)
+ m_fmAck = value;
+ else if (::strcmp(key, "AckSpeed") == 0)
+ m_fmAckSpeed = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "AckFrequency") == 0)
+ m_fmAckFrequency = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "AckDelay") == 0)
+ m_fmAckDelay = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "AckLevel") == 0)
+ m_fmAckLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "TimeoutLevel") == 0)
+ m_fmTimeoutLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CTCSSFrequency") == 0)
+ m_fmCTCSSFrequency = float(::atof(value));
+ else if (::strcmp(key, "CTCSSThreshold") == 0)
+ m_fmCTCSSThreshold = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "CTCSSLevel") == 0)
+ m_fmCTCSSLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "InputLevel") == 0)
+ m_fmInputLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "OutputLevel") == 0)
+ m_fmOutputLevel = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "KerchunkTime") == 0)
+ m_fmKerchunkTime = (unsigned int)::atoi(value);
+ else if (::strcmp(key, "HangTime") == 0)
+ m_fmHangTime = (unsigned int)::atoi(value);
} else if (section == SECTION_DSTAR_NETWORK) {
if (::strcmp(key, "Enable") == 0)
m_dstarNetworkEnabled = ::atoi(value) == 1;
@@ -1388,6 +1462,121 @@ unsigned int CConf::getPOCSAGFrequency() const
return m_pocsagFrequency;
}
+bool CConf::getFMEnabled() const
+{
+ return m_fmEnabled;
+}
+
+std::string CConf::getFMCallsign() const
+{
+ return m_fmCallsign;
+}
+
+unsigned int CConf::getFMCallsignSpeed() const
+{
+ return m_fmCallsignSpeed;
+}
+
+unsigned int CConf::getFMCallsignFrequency() const
+{
+ return m_fmCallsignFrequency;
+}
+
+unsigned int CConf::getFMCallsignTime() const
+{
+ return m_fmCallsignTime;
+}
+
+unsigned int CConf::getFMCallsignHoldoff() const
+{
+ return m_fmCallsignHoldoff;
+}
+
+unsigned int CConf::getFMCallsignHighLevel() const
+{
+ return m_fmCallsignHighLevel;
+}
+
+unsigned int CConf::getFMCallsignLowLevel() const
+{
+ return m_fmCallsignLowLevel;
+}
+
+bool CConf::getFMCallsignAtStart() const
+{
+ return m_fmCallsignAtStart;
+}
+
+bool CConf::getFMCallsignAtEnd() const
+{
+ return m_fmCallsignAtEnd;
+}
+
+std::string CConf::getFMAck() const
+{
+ return m_fmAck;
+}
+
+unsigned int CConf::getFMAckSpeed() const
+{
+ return m_fmAckSpeed;
+}
+
+unsigned int CConf::getFMAckFrequency() const
+{
+ return m_fmAckFrequency;
+}
+
+unsigned int CConf::getFMAckDelay() const
+{
+ return m_fmAckDelay;
+}
+
+unsigned int CConf::getFMAckLevel() const
+{
+ return m_fmAckLevel;
+}
+
+unsigned int CConf::getFMTimeoutLevel() const
+{
+ return m_fmTimeoutLevel;
+}
+
+float CConf::getFMCTCSSFrequency() const
+{
+ return m_fmCTCSSFrequency;
+}
+
+unsigned int CConf::getFMCTCSSThreshold() const
+{
+ return m_fmCTCSSThreshold;
+}
+
+unsigned int CConf::getFMCTCSSLevel() const
+{
+ return m_fmCTCSSLevel;
+}
+
+unsigned int CConf::getFMInputLevel() const
+{
+ return m_fmInputLevel;
+}
+
+unsigned int CConf::getFMOutputLevel() const
+{
+ return m_fmOutputLevel;
+}
+
+unsigned int CConf::getFMKerchunkTime() const
+{
+ return m_fmKerchunkTime;
+}
+
+unsigned int CConf::getFMHangTime() const
+{
+ return m_fmHangTime;
+}
+
bool CConf::getDStarNetworkEnabled() const
{
return m_dstarNetworkEnabled;
diff --git a/Conf.h b/Conf.h
index c76b202..d3189f9 100644
--- a/Conf.h
+++ b/Conf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
+ * Copyright (C) 2015-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
@@ -168,6 +168,31 @@ public:
bool getPOCSAGEnabled() const;
unsigned int getPOCSAGFrequency() const;
+ // The FM Section
+ bool getFMEnabled() const;
+ std::string getFMCallsign() const;
+ unsigned int getFMCallsignSpeed() const;
+ unsigned int getFMCallsignFrequency() const;
+ unsigned int getFMCallsignTime() const;
+ unsigned int getFMCallsignHoldoff() const;
+ unsigned int getFMCallsignHighLevel() const;
+ unsigned int getFMCallsignLowLevel() const;
+ bool getFMCallsignAtStart() const;
+ bool getFMCallsignAtEnd() const;
+ std::string getFMAck() const;
+ unsigned int getFMAckSpeed() const;
+ unsigned int getFMAckFrequency() const;
+ unsigned int getFMAckDelay() const;
+ unsigned int getFMAckLevel() const;
+ unsigned int getFMTimeoutLevel() const;
+ float getFMCTCSSFrequency() const;
+ unsigned int getFMCTCSSThreshold() const;
+ unsigned int getFMCTCSSLevel() const;
+ unsigned int getFMInputLevel() const;
+ unsigned int getFMOutputLevel() const;
+ unsigned int getFMKerchunkTime() const;
+ unsigned int getFMHangTime() const;
+
// The D-Star Network section
bool getDStarNetworkEnabled() const;
std::string getDStarGatewayAddress() const;
@@ -403,6 +428,30 @@ private:
bool m_pocsagEnabled;
unsigned int m_pocsagFrequency;
+ bool m_fmEnabled;
+ std::string m_fmCallsign;
+ unsigned int m_fmCallsignSpeed;
+ unsigned int m_fmCallsignFrequency;
+ unsigned int m_fmCallsignTime;
+ unsigned int m_fmCallsignHoldoff;
+ unsigned int m_fmCallsignHighLevel;
+ unsigned int m_fmCallsignLowLevel;
+ bool m_fmCallsignAtStart;
+ bool m_fmCallsignAtEnd;
+ std::string m_fmAck;
+ unsigned int m_fmAckSpeed;
+ unsigned int m_fmAckFrequency;
+ unsigned int m_fmAckDelay;
+ unsigned int m_fmAckLevel;
+ unsigned int m_fmTimeoutLevel;
+ float m_fmCTCSSFrequency;
+ unsigned int m_fmCTCSSThreshold;
+ unsigned int m_fmCTCSSLevel;
+ unsigned int m_fmInputLevel;
+ unsigned int m_fmOutputLevel;
+ unsigned int m_fmKerchunkTime;
+ unsigned int m_fmHangTime;
+
bool m_dstarNetworkEnabled;
std::string m_dstarGatewayAddress;
unsigned int m_dstarGatewayPort;
diff --git a/MMDVM.ini b/MMDVM.ini
index d6a8d84..6bdeed2 100644
--- a/MMDVM.ini
+++ b/MMDVM.ini
@@ -138,6 +138,31 @@ RemoteGateway=0
Enable=1
Frequency=439987500
+[FM]
+Enable=1
+Callsign=G4KLX
+CallsignSpeed=20
+CallsignFrequency=1000
+CallsignTime=10
+CallsignHoldoff=1
+CallsignHighLevel=80
+CallsignLowLevel=40
+CallsignAtStart=1
+CallsignAtEnd=1
+Ack=K
+AckSpeed=20
+AckFrequency=1750
+AckDelay=1000
+AckLevel=80
+TimeoutLevel=80
+CTCSSFrequency=88.4
+CTCSSThreshold=100
+CTCSSLevel=5
+InputLevel=50
+OutputLevel=50
+KerchunkTime=0
+HangTime=7
+
[D-Star Network]
Enable=1
GatewayAddress=127.0.0.1
diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp
index 53f6d1f..748f3f7 100644
--- a/MMDVMHost.cpp
+++ b/MMDVMHost.cpp
@@ -150,6 +150,7 @@ m_ysfEnabled(false),
m_p25Enabled(false),
m_nxdnEnabled(false),
m_pocsagEnabled(false),
+m_fmEnabled(false),
m_cwIdTime(0U),
m_dmrLookup(NULL),
m_nxdnLookup(NULL),
@@ -605,6 +606,63 @@ int CMMDVMHost::run()
pocsagTimer.start();
}
+ if (m_fmEnabled) {
+ std::string callsign = m_conf.getFMCallsign();
+ unsigned int callsignSpeed = m_conf.getFMCallsignSpeed();
+ unsigned int callsignFrequency = m_conf.getFMCallsignFrequency();
+ unsigned int callsignTime = m_conf.getFMCallsignTime();
+ unsigned int callsignHoldoff = m_conf.getFMCallsignHoldoff();
+ unsigned int callsignHighLevel = m_conf.getFMCallsignHighLevel();
+ unsigned int callsignLowLevel = m_conf.getFMCallsignLowLevel();
+ bool callsignAtStart = m_conf.getFMCallsignAtStart();
+ bool callsignAtEnd = m_conf.getFMCallsignAtEnd();
+ std::string ack = m_conf.getFMCallsign();
+ unsigned int ackSpeed = m_conf.getFMAckSpeed();
+ unsigned int ackFrequency = m_conf.getFMAckFrequency();
+ unsigned int ackDelay = m_conf.getFMAckDelay();
+ unsigned int ackLevel = m_conf.getFMAckLevel();
+ unsigned int timeout = m_conf.getTimeout();
+ unsigned int timeoutLevel = m_conf.getFMTimeoutLevel();
+ float ctcssFrequency = m_conf.getFMCTCSSFrequency();
+ unsigned int ctcssThreshold = m_conf.getFMCTCSSThreshold();
+ unsigned int ctcssLevel = m_conf.getFMCTCSSLevel();
+ unsigned int inputLevel = m_conf.getFMInputLevel();
+ unsigned int outputLevel = m_conf.getFMOutputLevel();
+ unsigned int kerchunkTime = m_conf.getFMKerchunkTime();
+ unsigned int hangTime = m_conf.getFMHangTime();
+
+ LogInfo("FM RF Parameters");
+ LogInfo(" Callsign: %s", callsign.c_str());
+ LogInfo(" Callsign Speed: %uWPM", callsignSpeed);
+ LogInfo(" Callsign Frequency: %uHz", callsignFrequency);
+ LogInfo(" Callsign Time: %umins", callsignTime);
+ LogInfo(" Callsign Holdoff: 1/%u", callsignHoldoff);
+ LogInfo(" Callsign High Level: %u%%", callsignHighLevel);
+ LogInfo(" Callsign Low Level: %u%%", callsignLowLevel);
+ LogInfo(" Callsign At Start: %s", callsignAtStart ? "yes" : "no");
+ LogInfo(" Callsign At End: %s", callsignAtEnd ? "yes" : "no");
+ LogInfo(" Ack: %s", ack.c_str());
+ LogInfo(" Ack Speed: %uWPM", ackSpeed);
+ LogInfo(" Ack Frequency: %uHz", ackFrequency);
+ LogInfo(" Ack Delay: %ums", ackDelay);
+ LogInfo(" Ack Level: %u%%", ackLevel);
+ LogInfo(" Timeout: %us", timeout);
+ LogInfo(" Timeout Level: %u%%", timeoutLevel);
+ LogInfo(" CTCSS Frequency: %.1fHz", ctcssFrequency);
+ LogInfo(" CTCSS Threshold: %u%%", ctcssThreshold);
+ LogInfo(" CTCSS Level: %u%%", ctcssLevel);
+ LogInfo(" Input Level: %u%%", inputLevel);
+ LogInfo(" Output Level: %u%%", outputLevel);
+ LogInfo(" Kerchunk Time: %us", kerchunkTime);
+ LogInfo(" Hang Time: %us", hangTime);
+
+ m_modem->setFMCallsignParams(callsign, callsignSpeed, callsignFrequency, callsignTime, callsignHoldoff, callsignHighLevel, callsignLowLevel, callsignAtStart, callsignAtEnd);
+ m_modem->setFMAckParams(ack, ackSpeed, ackFrequency, ackDelay, ackLevel);
+ m_modem->setFMTimeout(timeout, timeoutLevel);
+ m_modem->setFMCTCSS(ctcssFrequency, ctcssThreshold, ctcssLevel);
+ m_modem->setFMMisc(inputLevel, outputLevel, kerchunkTime, hangTime);
+ }
+
bool remoteControlEnabled = m_conf.getRemoteControlEnabled();
if (remoteControlEnabled) {
unsigned int port = m_conf.getRemoteControlPort();
@@ -1450,6 +1508,7 @@ void CMMDVMHost::readParams()
m_p25Enabled = m_conf.getP25Enabled();
m_nxdnEnabled = m_conf.getNXDNEnabled();
m_pocsagEnabled = m_conf.getPOCSAGEnabled();
+ m_fmEnabled = m_conf.getFMEnabled();
m_duplex = m_conf.getDuplex();
m_callsign = m_conf.getCallsign();
m_id = m_conf.getId();
@@ -1466,6 +1525,7 @@ void CMMDVMHost::readParams()
LogInfo(" P25: %s", m_p25Enabled ? "enabled" : "disabled");
LogInfo(" NXDN: %s", m_nxdnEnabled ? "enabled" : "disabled");
LogInfo(" POCSAG: %s", m_pocsagEnabled ? "enabled" : "disabled");
+ LogInfo(" FM: %s", m_fmEnabled ? "enabled" : "disabled");
}
void CMMDVMHost::setMode(unsigned char mode)
diff --git a/MMDVMHost.h b/MMDVMHost.h
index 177989a..de22de2 100644
--- a/MMDVMHost.h
+++ b/MMDVMHost.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
+ * Copyright (C) 2015-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
@@ -93,6 +93,7 @@ private:
bool m_p25Enabled;
bool m_nxdnEnabled;
bool m_pocsagEnabled;
+ bool m_fmEnabled;
unsigned int m_cwIdTime;
CDMRLookup* m_dmrLookup;
CNXDNLookup* m_nxdnLookup;
diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj
index 7b2121c..812c7a4 100644
--- a/MMDVMHost.vcxproj
+++ b/MMDVMHost.vcxproj
@@ -238,6 +238,8 @@
+
+
@@ -327,6 +329,8 @@
+
+
diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters
index 3b299d3..fb8a362 100644
--- a/MMDVMHost.vcxproj.filters
+++ b/MMDVMHost.vcxproj.filters
@@ -293,6 +293,12 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
@@ -550,5 +556,11 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
\ No newline at end of file
diff --git a/UserDB.cpp b/UserDB.cpp
index 9984d63..8c7301b 100644
--- a/UserDB.cpp
+++ b/UserDB.cpp
@@ -42,7 +42,7 @@ bool CUserDB::lookup(unsigned int id, class CUserDBentry *entry)
if (entry != NULL)
*entry = m_table.at(id);
else
- m_table.at(id);
+ (void)m_table.at(id);
rv = true;
} catch (...) {
@@ -116,8 +116,8 @@ bool CUserDB::makeindex(char* buf, std::unordered_map& index)
}
try {
- index.at(keyRADIO_ID);
- index.at(keyCALLSIGN);
+ (void)index.at(keyRADIO_ID);
+ (void)index.at(keyCALLSIGN);
return true;
} catch (...) {
return false;
@@ -144,8 +144,8 @@ void CUserDB::parse(char* buf, std::unordered_map& index)
}
try {
- ptr.at(keyRADIO_ID);
- ptr.at(keyCALLSIGN);
+ (void)ptr.at(keyRADIO_ID);
+ (void)ptr.at(keyCALLSIGN);
} catch (...) {
return;
}