Remove the DMRC startup message.

This commit is contained in:
Jonathan Naylor 2026-07-13 16:40:43 +01:00
parent 39694753b1
commit b7d15b81a1
9 changed files with 58 additions and 315 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2025 by Jonathan Naylor G4KLX
* Copyright (C) 2015-2026 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -30,7 +30,6 @@ const int BUFFER_SIZE = 500;
enum class SECTION {
NONE,
GENERAL,
INFO,
LOG,
MQTT,
CWID,
@ -96,15 +95,6 @@ m_id(0U),
m_timeout(120U),
m_duplex(true),
m_daemon(false),
m_rxFrequency(0U),
m_txFrequency(0U),
m_power(0U),
m_latitude(0.0F),
m_longitude(0.0F),
m_height(0),
m_location(),
m_description(),
m_url(),
m_logMQTTLevel(0U),
m_logDisplayLevel(0U),
m_mqttHost("127.0.0.1"),
@ -134,6 +124,8 @@ m_modemModemAddress(),
m_modemModemPort(0U),
m_modemLocalAddress(),
m_modemLocalPort(0U),
m_modemRXFrequency(0U),
m_modemTXFrequency(0U),
m_modemRXInvert(false),
m_modemTXInvert(false),
m_modemPTTInvert(false),
@ -391,8 +383,6 @@ bool CConf::read()
if (buffer[0U] == '[') {
if (::strncmp(buffer, "[General]", 9U) == 0)
section = SECTION::GENERAL;
else if (::strncmp(buffer, "[Info]", 6U) == 0)
section = SECTION::INFO;
else if (::strncmp(buffer, "[Log]", 5U) == 0)
section = SECTION::LOG;
else if (::strncmp(buffer, "[MQTT]", 6U) == 0)
@ -525,25 +515,6 @@ bool CConf::read()
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang = m_nxdnNetworkModeHang = m_fmNetworkModeHang = (unsigned int)::atoi(value);
else if (::strcmp(key, "Daemon") == 0)
m_daemon = ::atoi(value) == 1;
} else if (section == SECTION::INFO) {
if (::strcmp(key, "TXFrequency") == 0)
m_pocsagFrequency = m_txFrequency = (unsigned int)::atoi(value);
else if (::strcmp(key, "RXFrequency") == 0)
m_rxFrequency = (unsigned int)::atoi(value);
else if (::strcmp(key, "Power") == 0)
m_power = (unsigned int)::atoi(value);
else if (::strcmp(key, "Latitude") == 0)
m_latitude = float(::atof(value));
else if (::strcmp(key, "Longitude") == 0)
m_longitude = float(::atof(value));
else if (::strcmp(key, "Height") == 0)
m_height = ::atoi(value);
else if (::strcmp(key, "Location") == 0)
m_location = value;
else if (::strcmp(key, "Description") == 0)
m_description = value;
else if (::strcmp(key, "URL") == 0)
m_url = value;
} else if (section == SECTION::LOG) {
if (::strcmp(key, "MQTTLevel") == 0)
m_logMQTTLevel = (unsigned int)::atoi(value);
@ -608,6 +579,10 @@ bool CConf::read()
m_modemLocalAddress = value;
else if (::strcmp(key, "LocalPort") == 0)
m_modemLocalPort = (unsigned short)::atoi(value);
else if (::strcmp(key, "TXFrequency") == 0)
m_pocsagFrequency = m_modemTXFrequency = (unsigned int)::atoi(value);
else if (::strcmp(key, "RXFrequency") == 0)
m_modemRXFrequency = (unsigned int)::atoi(value);
else if (::strcmp(key, "RXInvert") == 0)
m_modemRXInvert = ::atoi(value) == 1;
else if (::strcmp(key, "TXInvert") == 0)
@ -1154,51 +1129,6 @@ bool CConf::getDaemon() const
return m_daemon;
}
unsigned int CConf::getRXFrequency() const
{
return m_rxFrequency;
}
unsigned int CConf::getTXFrequency() const
{
return m_txFrequency;
}
unsigned int CConf::getPower() const
{
return m_power;
}
float CConf::getLatitude() const
{
return m_latitude;
}
float CConf::getLongitude() const
{
return m_longitude;
}
int CConf::getHeight() const
{
return m_height;
}
std::string CConf::getLocation() const
{
return m_location;
}
std::string CConf::getDescription() const
{
return m_description;
}
std::string CConf::getURL() const
{
return m_url;
}
unsigned int CConf::getLogMQTTLevel() const
{
return m_logMQTTLevel;
@ -1328,6 +1258,16 @@ unsigned short CConf::getModemLocalPort() const
return m_modemLocalPort;
}
unsigned int CConf::getModemRXFrequency() const
{
return m_modemRXFrequency;
}
unsigned int CConf::getModemTXFrequency() const
{
return m_modemTXFrequency;
}
bool CConf::getModemRXInvert() const
{
return m_modemRXInvert;

25
Conf.h
View file

@ -39,17 +39,6 @@ public:
bool getDuplex() const;
bool getDaemon() const;
// The Info section
unsigned int getRXFrequency() const;
unsigned int getTXFrequency() const;
unsigned int getPower() const;
float getLatitude() const;
float getLongitude() const;
int getHeight() const;
std::string getLocation() const;
std::string getDescription() const;
std::string getURL() const;
// The Log section
unsigned int getLogMQTTLevel() const;
unsigned int getLogDisplayLevel() const;
@ -90,6 +79,8 @@ public:
unsigned short getModemModemPort() const;
std::string getModemLocalAddress() const;
unsigned short getModemLocalPort() const;
unsigned int getModemRXFrequency() const;
unsigned int getModemTXFrequency() const;
bool getModemRXInvert() const;
bool getModemTXInvert() const;
bool getModemPTTInvert() const;
@ -359,16 +350,6 @@ private:
bool m_duplex;
bool m_daemon;
unsigned int m_rxFrequency;
unsigned int m_txFrequency;
unsigned int m_power;
float m_latitude;
float m_longitude;
int m_height;
std::string m_location;
std::string m_description;
std::string m_url;
unsigned int m_logMQTTLevel;
unsigned int m_logDisplayLevel;
@ -403,6 +384,8 @@ private:
unsigned short m_modemModemPort;
std::string m_modemLocalAddress;
unsigned short m_modemLocalPort;
unsigned int m_modemRXFrequency;
unsigned int m_modemTXFrequency;
bool m_modemRXInvert;
bool m_modemTXInvert;
bool m_modemPTTInvert;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2021,2023 by Jonathan Naylor G4KLX
* Copyright (C) 2015-2021,2023,2026 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
@ -32,30 +32,23 @@ const unsigned int BUFFER_LENGTH = 500U;
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned short port, const std::string& localAddress, unsigned short localPort, unsigned int id, bool duplex, const char* version, bool slot1, bool slot2, HW_TYPE hwType, bool debug) :
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned short port, const std::string& localAddress, unsigned short localPort, unsigned int id, bool duplex, const char* version, bool slot1, bool slot2, bool debug) :
m_addressStr(address),
m_addr(),
m_addrLen(0U),
m_port(port),
m_id(nullptr),
m_duplex(duplex),
m_version(version),
m_debug(debug),
m_socket(localAddress, localPort),
m_enabled(false),
m_slot1(slot1),
m_slot2(slot2),
m_hwType(hwType),
m_buffer(nullptr),
m_streamId(nullptr),
m_rxData(1000U, "DMR Network"),
m_beacon(false),
m_random(),
m_callsign(),
m_rxFrequency(0U),
m_txFrequency(0U),
m_power(0U),
m_colorCode(0U),
m_pingTimer(1000U, 10U)
{
assert(!address.empty());
@ -90,15 +83,6 @@ CDMRNetwork::~CDMRNetwork()
delete[] m_id;
}
void CDMRNetwork::setConfig(const std::string & callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode)
{
m_callsign = callsign;
m_rxFrequency = rxFrequency;
m_txFrequency = txFrequency;
m_power = power;
m_colorCode = colorCode;
}
bool CDMRNetwork::open()
{
if (m_addrLen == 0U) {
@ -315,7 +299,7 @@ void CDMRNetwork::clock(unsigned int ms)
{
m_pingTimer.clock(ms);
if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) {
writeConfig();
writePing();
m_pingTimer.start();
}
@ -348,91 +332,16 @@ void CDMRNetwork::clock(unsigned int ms)
}
}
bool CDMRNetwork::writeConfig()
bool CDMRNetwork::writePing()
{
const char* software;
char slots = '0';
if (m_duplex) {
if (m_slot1 && m_slot2)
slots = '3';
else if (m_slot1 && !m_slot2)
slots = '1';
else if (!m_slot1 && m_slot2)
slots = '2';
unsigned char buffer[4U];
switch (m_hwType) {
case HW_TYPE::MMDVM:
software = "MMDVM";
break;
case HW_TYPE::MMDVM_HS:
software = "MMDVM_MMDVM_HS";
break;
case HW_TYPE::MMDVM_HS_DUAL_HAT:
software = "MMDVM_MMDVM_HS_Dual_Hat";
break;
case HW_TYPE::NANO_HOTSPOT:
software = "MMDVM_Nano_hotSPOT";
break;
default:
software = "MMDVM_Unknown";
break;
}
} else {
slots = '4';
buffer[0U] = 'D';
buffer[1U] = 'M';
buffer[2U] = 'R';
buffer[3U] = 'P';
switch (m_hwType) {
case HW_TYPE::MMDVM:
software = "MMDVM_DMO";
break;
case HW_TYPE::DVMEGA:
software = "MMDVM_DVMega";
break;
case HW_TYPE::MMDVM_ZUMSPOT:
software = "MMDVM_ZUMspot";
break;
case HW_TYPE::MMDVM_HS_HAT:
software = "MMDVM_MMDVM_HS_Hat";
break;
case HW_TYPE::MMDVM_HS_DUAL_HAT:
software = "MMDVM_MMDVM_HS_Dual_Hat";
break;
case HW_TYPE::NANO_HOTSPOT:
software = "MMDVM_Nano_hotSPOT";
break;
case HW_TYPE::NANO_DV:
software = "MMDVM_Nano_DV";
break;
case HW_TYPE::D2RG_MMDVM_HS:
software = "MMDVM_D2RG_MMDVM_HS";
break;
case HW_TYPE::MMDVM_HS:
software = "MMDVM_MMDVM_HS";
break;
case HW_TYPE::OPENGD77_HS:
software = "MMDVM_OpenGD77_HS";
break;
case HW_TYPE::SKYBRIDGE:
software = "MMDVM_SkyBridge";
break;
default:
software = "MMDVM_Unknown";
break;
}
}
unsigned int power = m_power;
if (power > 99U)
power = 99U;
char buffer[150U];
::memcpy(buffer + 0U, "DMRC", 4U);
::memcpy(buffer + 4U, m_id, 4U);
::sprintf(buffer + 8U, "%-8.8s%09u%09u%02u%02u%c%-40.40s%-40.40s",
m_callsign.c_str(), m_rxFrequency, m_txFrequency, power, m_colorCode, slots, m_version,
software);
return write((unsigned char*)buffer, 119U);
return write(buffer, 4U);
}
bool CDMRNetwork::wantsBeacon()

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018,2020,2021,2023 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020,2021,2023,2026 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
@ -34,11 +34,9 @@
class CDMRNetwork
{
public:
CDMRNetwork(const std::string& gatewayAddress, unsigned short gatewayPort, const std::string& localAddress, unsigned short localPort, unsigned int id, bool duplex, const char* version, bool slot1, bool slot2, HW_TYPE hwType, bool debug);
CDMRNetwork(const std::string& gatewayAddress, unsigned short gatewayPort, const std::string& localAddress, unsigned short localPort, unsigned int id, bool duplex, const char* version, bool slot1, bool slot2, bool debug);
~CDMRNetwork();
void setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode);
bool open();
void enable(bool enabled);
@ -66,26 +64,19 @@ private:
unsigned short m_port;
uint8_t* m_id;
bool m_duplex;
const char* m_version;
bool m_debug;
CUDPSocket m_socket;
bool m_enabled;
bool m_slot1;
bool m_slot2;
HW_TYPE m_hwType;
unsigned char* m_buffer;
uint32_t* m_streamId;
CRingBuffer<unsigned char> m_rxData;
bool m_beacon;
std::mt19937 m_random;
std::string m_callsign;
unsigned int m_rxFrequency;
unsigned int m_txFrequency;
unsigned int m_power;
unsigned int m_colorCode;
CTimer m_pingTimer;
bool writeConfig();
bool writePing();
bool write(const unsigned char* data, unsigned int length);
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018,2020,2021,2023,2025 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020,2021,2023,2025,2026 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
@ -51,21 +51,6 @@ const unsigned char TAG_RSSI = 0x04U;
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
enum class HW_TYPE {
MMDVM,
DVMEGA,
MMDVM_ZUMSPOT,
MMDVM_HS_HAT,
MMDVM_HS_DUAL_HAT,
NANO_HOTSPOT,
NANO_DV,
D2RG_MMDVM_HS,
MMDVM_HS,
OPENGD77_HS,
SKYBRIDGE,
UNKNOWN
};
enum class RPT_RF_STATE {
LISTENING,
LATE_ENTRY,

View file

@ -1587,8 +1587,8 @@ bool CMMDVMHost::createModem()
#if defined(USE_NXDN)
unsigned int nxdnTXHang = m_conf.getNXDNTXHang();
#endif
unsigned int rxFrequency = m_conf.getRXFrequency();
unsigned int txFrequency = m_conf.getTXFrequency();
unsigned int rxFrequency = m_conf.getModemRXFrequency();
unsigned int txFrequency = m_conf.getModemTXFrequency();
#if defined(USE_POCSAG)
unsigned int pocsagFrequency = m_conf.getPOCSAGFrequency();
#else
@ -1838,7 +1838,6 @@ bool CMMDVMHost::createDMRNetwork()
unsigned int jitter = m_conf.getDMRNetworkJitter();
bool slot1 = m_conf.getDMRNetworkSlot1();
bool slot2 = m_conf.getDMRNetworkSlot2();
HW_TYPE hwType = m_modem->getHWType();
m_dmrNetModeHang = m_conf.getDMRNetworkModeHang();
LogInfo("DMR Network Parameters");
@ -1851,21 +1850,8 @@ bool CMMDVMHost::createDMRNetwork()
LogInfo(" Slot 2: %s", slot2 ? "enabled" : "disabled");
LogInfo(" Mode Hang: %us", m_dmrNetModeHang);
m_dmrNetwork = new CDMRNetwork(gatewayAddress, gatewayPort, localAddress, localPort, id, m_duplex, VERSION, slot1, slot2, hwType, debug);
m_dmrNetwork = new CDMRNetwork(gatewayAddress, gatewayPort, localAddress, localPort, id, m_duplex, VERSION, slot1, slot2, debug);
unsigned int rxFrequency = m_conf.getRXFrequency();
unsigned int txFrequency = m_conf.getTXFrequency();
unsigned int power = m_conf.getPower();
unsigned int colorCode = m_conf.getDMRColorCode();
LogInfo("Info Parameters");
LogInfo(" Callsign: %s", m_callsign.c_str());
LogInfo(" RX Frequency: %uHz", rxFrequency);
LogInfo(" TX Frequency: %uHz", txFrequency);
LogInfo(" Power: %uW", power);
m_dmrNetwork->setConfig(m_callsign, rxFrequency, txFrequency, power, colorCode);
bool ret = m_dmrNetwork->open();
if (!ret) {
delete m_dmrNetwork;

View file

@ -8,18 +8,6 @@ RFModeHang=10
NetModeHang=3
Daemon=0
[Info]
RXFrequency=435000000
TXFrequency=435000000
Power=1
# The following lines are only needed if a direct connection to a DMR master is being used
Latitude=0.0
Longitude=0.0
Height=0
Location=Nowhere
Description=Multi-Mode Repeater
URL=www.google.co.uk
[Log]
# Logging levels, 0=No logging
MQTTLevel=1
@ -64,6 +52,9 @@ ModemPort=3334
LocalAddress=192.168.2.1
LocalPort=3335
RXFrequency=435000000
TXFrequency=435000000
TXInvert=1
RXInvert=0
PTTInvert=0

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2018,2020,2021,2023,2025 by Jonathan Naylor G4KLX
* Copyright (C) 2011-2018,2020,2021,2023,2025,2026 by Jonathan Naylor G4KLX
* Copyright (C) 2026 by Adrian Musceac YO8RZZ
*
* This program is free software; you can redistribute it and/or modify
@ -278,7 +278,6 @@ m_cd(false),
m_lockout(false),
m_error(false),
m_mode(MODE_IDLE),
m_hwType(HW_TYPE::UNKNOWN),
#if defined(USE_FM)
m_fmCallsign(),
m_fmCallsignSpeed(20U),
@ -2006,33 +2005,7 @@ bool CModem::readVersion()
CThread::sleep(10U);
RESP_TYPE_MMDVM resp = getResponse();
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_GET_VERSION)) {
if (::memcmp(m_buffer + 4U, "MMDVM ", 6U) == 0)
m_hwType = HW_TYPE::MMDVM;
else if (::memcmp(m_buffer + 23U, "MMDVM ", 6U) == 0)
m_hwType = HW_TYPE::MMDVM;
else if (::memcmp(m_buffer + 4U, "DVMEGA", 6U) == 0)
m_hwType = HW_TYPE::DVMEGA;
else if (::memcmp(m_buffer + 4U, "ZUMspot", 7U) == 0)
m_hwType = HW_TYPE::MMDVM_ZUMSPOT;
else if (::memcmp(m_buffer + 4U, "MMDVM_HS_Hat", 12U) == 0)
m_hwType = HW_TYPE::MMDVM_HS_HAT;
else if (::memcmp(m_buffer + 4U, "MMDVM_HS_Dual_Hat", 17U) == 0)
m_hwType = HW_TYPE::MMDVM_HS_DUAL_HAT;
else if (::memcmp(m_buffer + 4U, "Nano_hotSPOT", 12U) == 0)
m_hwType = HW_TYPE::NANO_HOTSPOT;
else if (::memcmp(m_buffer + 4U, "Nano_DV", 7U) == 0)
m_hwType = HW_TYPE::NANO_DV;
else if (::memcmp(m_buffer + 4U, "D2RG_MMDVM_HS", 13U) == 0)
m_hwType = HW_TYPE::D2RG_MMDVM_HS;
else if (::memcmp(m_buffer + 4U, "MMDVM_HS-", 9U) == 0)
m_hwType = HW_TYPE::MMDVM_HS;
else if (::memcmp(m_buffer + 4U, "OpenGD77_HS", 11U) == 0)
m_hwType = HW_TYPE::OPENGD77_HS;
else if (::memcmp(m_buffer + 4U, "SkyBridge", 9U) == 0)
m_hwType = HW_TYPE::SKYBRIDGE;
m_protocolVersion = m_buffer[3U];
switch (m_protocolVersion) {
case 1U:
LogInfo("MMDVM protocol version: 1, description: %.*s", m_length - 4U, m_buffer + 4U);
@ -2480,7 +2453,6 @@ bool CModem::setFrequency()
assert(m_port != nullptr);
unsigned char buffer[20U];
unsigned char len;
#if defined(USE_POCSAG)
unsigned int pocsagFrequency = 433000000U;
@ -2488,29 +2460,23 @@ bool CModem::setFrequency()
pocsagFrequency = m_pocsagFrequency;
#endif
if (m_hwType == HW_TYPE::DVMEGA)
len = 12U;
else {
buffer[12U] = (unsigned char)(m_rfLevel * 2.55F + 0.5F);
buffer[12U] = (unsigned char)(m_rfLevel * 2.55F + 0.5F);
#if defined(USE_POCSAG)
buffer[13U] = (pocsagFrequency >> 0) & 0xFFU;
buffer[14U] = (pocsagFrequency >> 8) & 0xFFU;
buffer[15U] = (pocsagFrequency >> 16) & 0xFFU;
buffer[16U] = (pocsagFrequency >> 24) & 0xFFU;
buffer[13U] = (pocsagFrequency >> 0) & 0xFFU;
buffer[14U] = (pocsagFrequency >> 8) & 0xFFU;
buffer[15U] = (pocsagFrequency >> 16) & 0xFFU;
buffer[16U] = (pocsagFrequency >> 24) & 0xFFU;
#else
buffer[13U] = 0U;
buffer[14U] = 0U;
buffer[15U] = 0U;
buffer[16U] = 0U;
buffer[13U] = 0U;
buffer[14U] = 0U;
buffer[15U] = 0U;
buffer[16U] = 0U;
#endif
len = 17U;
}
buffer[0U] = MMDVM_FRAME_START;
buffer[1U] = len;
buffer[1U] = 17U;
buffer[2U] = MMDVM_SET_FREQ;
@ -2526,10 +2492,10 @@ bool CModem::setFrequency()
buffer[10U] = (m_txFrequency >> 16) & 0xFFU;
buffer[11U] = (m_txFrequency >> 24) & 0xFFU;
// CUtils::dump(1U, "Written", buffer, len);
// CUtils::dump(1U, "Written", buffer, 17U);
int ret = m_port->write(buffer, len);
if (ret != len)
int ret = m_port->write(buffer, 17U);
if (ret != 17)
return false;
unsigned int count = 0U;
@ -2659,11 +2625,6 @@ RESP_TYPE_MMDVM CModem::getResponse()
return RESP_TYPE_MMDVM::OK;
}
HW_TYPE CModem::getHWType() const
{
return m_hwType;
}
unsigned char CModem::getMode() const
{
return m_mode;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2018,2020,2021,2023,2025 by Jonathan Naylor G4KLX
* Copyright (C) 2011-2018,2020,2021,2023,2025,2026 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
@ -199,8 +199,6 @@ public:
bool sendCWId(const std::string& callsign);
HW_TYPE getHWType() const;
void clock(unsigned int ms);
void close();
@ -361,7 +359,6 @@ private:
bool m_lockout;
bool m_error;
unsigned char m_mode;
HW_TYPE m_hwType;
#if defined(USE_FM)
std::string m_fmCallsign;
unsigned int m_fmCallsignSpeed;
@ -418,8 +415,8 @@ private:
RESP_TYPE_MMDVM getResponse();
// Added these for buffering serial data from display:
unsigned char m_serialDataBuffer[256];
unsigned int m_serialDataLen;
unsigned char m_serialDataBuffer[256];
unsigned int m_serialDataLen;
};
#endif