Beginnings of FM support.

This commit is contained in:
Jonathan Naylor 2020-04-09 22:02:47 +01:00
parent 4c4ea170b6
commit 535ddba1a0
8 changed files with 351 additions and 11 deletions

197
Conf.cpp
View File

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

51
Conf.h
View File

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

View File

@ -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

View File

@ -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)

View File

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

View File

@ -238,6 +238,8 @@
<ClInclude Include="Timer.h" />
<ClInclude Include="UDPSocket.h" />
<ClInclude Include="UMP.h" />
<ClInclude Include="UserDB.h" />
<ClInclude Include="UserDBentry.h" />
<ClInclude Include="Utils.h" />
<ClInclude Include="Version.h" />
<ClInclude Include="YSFControl.h" />
@ -327,6 +329,8 @@
<ClCompile Include="Timer.cpp" />
<ClCompile Include="UDPSocket.cpp" />
<ClCompile Include="UMP.cpp" />
<ClCompile Include="UserDB.cpp" />
<ClCompile Include="UserDBentry.cpp" />
<ClCompile Include="Utils.cpp" />
<ClCompile Include="YSFNetwork.cpp" />
<ClCompile Include="YSFPayload.cpp" />

View File

@ -293,6 +293,12 @@
<ClInclude Include="TFTSurenoo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UserDB.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UserDBentry.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="BPTC19696.cpp">
@ -550,5 +556,11 @@
<ClCompile Include="TFTSurenoo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UserDB.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UserDBentry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -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<std::string, int>& 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<std::string, int>& index)
}
try {
ptr.at(keyRADIO_ID);
ptr.at(keyCALLSIGN);
(void)ptr.at(keyRADIO_ID);
(void)ptr.at(keyCALLSIGN);
} catch (...) {
return;
}