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; }