mirror of
https://github.com/g4klx/MMDVMHost.git
synced 2025-12-06 05:32:00 +01:00
Change all of the enums to the modern format.
This commit is contained in:
parent
78fc96b0a5
commit
43f8b2f6f0
238
Conf.cpp
238
Conf.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2023 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2023,2025 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
|
||||||
|
|
@ -27,41 +27,41 @@
|
||||||
|
|
||||||
const int BUFFER_SIZE = 500;
|
const int BUFFER_SIZE = 500;
|
||||||
|
|
||||||
enum SECTION {
|
enum class SECTION {
|
||||||
SECTION_NONE,
|
NONE,
|
||||||
SECTION_GENERAL,
|
GENERAL,
|
||||||
SECTION_INFO,
|
INFO,
|
||||||
SECTION_LOG,
|
LOG,
|
||||||
SECTION_CWID,
|
CWID,
|
||||||
SECTION_DMRID_LOOKUP,
|
DMRID_LOOKUP,
|
||||||
SECTION_NXDNID_LOOKUP,
|
NXDNID_LOOKUP,
|
||||||
SECTION_MODEM,
|
MODEM,
|
||||||
SECTION_TRANSPARENT,
|
TRANSPARENT,
|
||||||
SECTION_DSTAR,
|
DSTAR,
|
||||||
SECTION_DMR,
|
DMR,
|
||||||
SECTION_FUSION,
|
FUSION,
|
||||||
SECTION_P25,
|
P25,
|
||||||
SECTION_NXDN,
|
NXDN,
|
||||||
SECTION_M17,
|
M17,
|
||||||
SECTION_POCSAG,
|
POCSAG,
|
||||||
SECTION_FM,
|
FM,
|
||||||
SECTION_AX25,
|
AX25,
|
||||||
SECTION_DSTAR_NETWORK,
|
DSTAR_NETWORK,
|
||||||
SECTION_DMR_NETWORK,
|
DMR_NETWORK,
|
||||||
SECTION_FUSION_NETWORK,
|
FUSION_NETWORK,
|
||||||
SECTION_P25_NETWORK,
|
P25_NETWORK,
|
||||||
SECTION_NXDN_NETWORK,
|
NXDN_NETWORK,
|
||||||
SECTION_M17_NETWORK,
|
M17_NETWORK,
|
||||||
SECTION_POCSAG_NETWORK,
|
POCSAG_NETWORK,
|
||||||
SECTION_FM_NETWORK,
|
FM_NETWORK,
|
||||||
SECTION_AX25_NETWORK,
|
AX25_NETWORK,
|
||||||
SECTION_TFTSERIAL,
|
TFTSERIAL,
|
||||||
SECTION_HD44780,
|
HD44780,
|
||||||
SECTION_NEXTION,
|
NEXTION,
|
||||||
SECTION_OLED,
|
OLED,
|
||||||
SECTION_LCDPROC,
|
LCDPROC,
|
||||||
SECTION_LOCK_FILE,
|
LOCK_FILE,
|
||||||
SECTION_REMOTE_CONTROL
|
REMOTE_CONTROL
|
||||||
};
|
};
|
||||||
|
|
||||||
CConf::CConf(const std::string& file) :
|
CConf::CConf(const std::string& file) :
|
||||||
|
|
@ -139,12 +139,12 @@ m_dstarBlackList(),
|
||||||
m_dstarWhiteList(),
|
m_dstarWhiteList(),
|
||||||
m_dstarAckReply(true),
|
m_dstarAckReply(true),
|
||||||
m_dstarAckTime(750U),
|
m_dstarAckTime(750U),
|
||||||
m_dstarAckMessage(DSTAR_ACK_BER),
|
m_dstarAckMessage(DSTAR_ACK::BER),
|
||||||
m_dstarErrorReply(true),
|
m_dstarErrorReply(true),
|
||||||
m_dstarRemoteGateway(false),
|
m_dstarRemoteGateway(false),
|
||||||
m_dstarModeHang(10U),
|
m_dstarModeHang(10U),
|
||||||
m_dmrEnabled(false),
|
m_dmrEnabled(false),
|
||||||
m_dmrBeacons(DMR_BEACONS_OFF),
|
m_dmrBeacons(DMR_BEACONS::OFF),
|
||||||
m_dmrBeaconInterval(60U),
|
m_dmrBeaconInterval(60U),
|
||||||
m_dmrBeaconDuration(3U),
|
m_dmrBeaconDuration(3U),
|
||||||
m_dmrId(0U),
|
m_dmrId(0U),
|
||||||
|
|
@ -160,7 +160,7 @@ m_dmrSlot2TGWhiteList(),
|
||||||
m_dmrCallHang(10U),
|
m_dmrCallHang(10U),
|
||||||
m_dmrTXHang(4U),
|
m_dmrTXHang(4U),
|
||||||
m_dmrModeHang(10U),
|
m_dmrModeHang(10U),
|
||||||
m_dmrOVCM(DMR_OVCM_OFF),
|
m_dmrOVCM(DMR_OVCM::OFF),
|
||||||
m_dmrProtect(false),
|
m_dmrProtect(false),
|
||||||
m_fusionEnabled(false),
|
m_fusionEnabled(false),
|
||||||
m_fusionLowDeviation(false),
|
m_fusionLowDeviation(false),
|
||||||
|
|
@ -361,7 +361,7 @@ bool CConf::read()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION section = SECTION_NONE;
|
SECTION section = SECTION::NONE;
|
||||||
|
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) {
|
while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) {
|
||||||
|
|
@ -370,73 +370,73 @@ bool CConf::read()
|
||||||
|
|
||||||
if (buffer[0U] == '[') {
|
if (buffer[0U] == '[') {
|
||||||
if (::strncmp(buffer, "[General]", 9U) == 0)
|
if (::strncmp(buffer, "[General]", 9U) == 0)
|
||||||
section = SECTION_GENERAL;
|
section = SECTION::GENERAL;
|
||||||
else if (::strncmp(buffer, "[Info]", 6U) == 0)
|
else if (::strncmp(buffer, "[Info]", 6U) == 0)
|
||||||
section = SECTION_INFO;
|
section = SECTION::INFO;
|
||||||
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
||||||
section = SECTION_LOG;
|
section = SECTION::LOG;
|
||||||
else if (::strncmp(buffer, "[CW Id]", 7U) == 0)
|
else if (::strncmp(buffer, "[CW Id]", 7U) == 0)
|
||||||
section = SECTION_CWID;
|
section = SECTION::CWID;
|
||||||
else if (::strncmp(buffer, "[DMR Id Lookup]", 15U) == 0)
|
else if (::strncmp(buffer, "[DMR Id Lookup]", 15U) == 0)
|
||||||
section = SECTION_DMRID_LOOKUP;
|
section = SECTION::DMRID_LOOKUP;
|
||||||
else if (::strncmp(buffer, "[NXDN Id Lookup]", 16U) == 0)
|
else if (::strncmp(buffer, "[NXDN Id Lookup]", 16U) == 0)
|
||||||
section = SECTION_NXDNID_LOOKUP;
|
section = SECTION::NXDNID_LOOKUP;
|
||||||
else if (::strncmp(buffer, "[Modem]", 7U) == 0)
|
else if (::strncmp(buffer, "[Modem]", 7U) == 0)
|
||||||
section = SECTION_MODEM;
|
section = SECTION::MODEM;
|
||||||
else if (::strncmp(buffer, "[Transparent Data]", 18U) == 0)
|
else if (::strncmp(buffer, "[Transparent Data]", 18U) == 0)
|
||||||
section = SECTION_TRANSPARENT;
|
section = SECTION::TRANSPARENT;
|
||||||
else if (::strncmp(buffer, "[D-Star]", 8U) == 0)
|
else if (::strncmp(buffer, "[D-Star]", 8U) == 0)
|
||||||
section = SECTION_DSTAR;
|
section = SECTION::DSTAR;
|
||||||
else if (::strncmp(buffer, "[DMR]", 5U) == 0)
|
else if (::strncmp(buffer, "[DMR]", 5U) == 0)
|
||||||
section = SECTION_DMR;
|
section = SECTION::DMR;
|
||||||
else if (::strncmp(buffer, "[System Fusion]", 15U) == 0)
|
else if (::strncmp(buffer, "[System Fusion]", 15U) == 0)
|
||||||
section = SECTION_FUSION;
|
section = SECTION::FUSION;
|
||||||
else if (::strncmp(buffer, "[P25]", 5U) == 0)
|
else if (::strncmp(buffer, "[P25]", 5U) == 0)
|
||||||
section = SECTION_P25;
|
section = SECTION::P25;
|
||||||
else if (::strncmp(buffer, "[NXDN]", 6U) == 0)
|
else if (::strncmp(buffer, "[NXDN]", 6U) == 0)
|
||||||
section = SECTION_NXDN;
|
section = SECTION::NXDN;
|
||||||
else if (::strncmp(buffer, "[M17]", 5U) == 0)
|
else if (::strncmp(buffer, "[M17]", 5U) == 0)
|
||||||
section = SECTION_M17;
|
section = SECTION::M17;
|
||||||
else if (::strncmp(buffer, "[POCSAG]", 8U) == 0)
|
else if (::strncmp(buffer, "[POCSAG]", 8U) == 0)
|
||||||
section = SECTION_POCSAG;
|
section = SECTION::POCSAG;
|
||||||
else if (::strncmp(buffer, "[FM]", 4U) == 0)
|
else if (::strncmp(buffer, "[FM]", 4U) == 0)
|
||||||
section = SECTION_FM;
|
section = SECTION::FM;
|
||||||
else if (::strncmp(buffer, "[AX.25]", 7U) == 0)
|
else if (::strncmp(buffer, "[AX.25]", 7U) == 0)
|
||||||
section = SECTION_AX25;
|
section = SECTION::AX25;
|
||||||
else if (::strncmp(buffer, "[D-Star Network]", 16U) == 0)
|
else if (::strncmp(buffer, "[D-Star Network]", 16U) == 0)
|
||||||
section = SECTION_DSTAR_NETWORK;
|
section = SECTION::DSTAR_NETWORK;
|
||||||
else if (::strncmp(buffer, "[DMR Network]", 13U) == 0)
|
else if (::strncmp(buffer, "[DMR Network]", 13U) == 0)
|
||||||
section = SECTION_DMR_NETWORK;
|
section = SECTION::DMR_NETWORK;
|
||||||
else if (::strncmp(buffer, "[System Fusion Network]", 23U) == 0)
|
else if (::strncmp(buffer, "[System Fusion Network]", 23U) == 0)
|
||||||
section = SECTION_FUSION_NETWORK;
|
section = SECTION::FUSION_NETWORK;
|
||||||
else if (::strncmp(buffer, "[P25 Network]", 13U) == 0)
|
else if (::strncmp(buffer, "[P25 Network]", 13U) == 0)
|
||||||
section = SECTION_P25_NETWORK;
|
section = SECTION::P25_NETWORK;
|
||||||
else if (::strncmp(buffer, "[NXDN Network]", 14U) == 0)
|
else if (::strncmp(buffer, "[NXDN Network]", 14U) == 0)
|
||||||
section = SECTION_NXDN_NETWORK;
|
section = SECTION::NXDN_NETWORK;
|
||||||
else if (::strncmp(buffer, "[M17 Network]", 13U) == 0)
|
else if (::strncmp(buffer, "[M17 Network]", 13U) == 0)
|
||||||
section = SECTION_M17_NETWORK;
|
section = SECTION::M17_NETWORK;
|
||||||
else if (::strncmp(buffer, "[POCSAG Network]", 16U) == 0)
|
else if (::strncmp(buffer, "[POCSAG Network]", 16U) == 0)
|
||||||
section = SECTION_POCSAG_NETWORK;
|
section = SECTION::POCSAG_NETWORK;
|
||||||
else if (::strncmp(buffer, "[FM Network]", 12U) == 0)
|
else if (::strncmp(buffer, "[FM Network]", 12U) == 0)
|
||||||
section = SECTION_FM_NETWORK;
|
section = SECTION::FM_NETWORK;
|
||||||
else if (::strncmp(buffer, "[AX.25 Network]", 15U) == 0)
|
else if (::strncmp(buffer, "[AX.25 Network]", 15U) == 0)
|
||||||
section = SECTION_AX25_NETWORK;
|
section = SECTION::AX25_NETWORK;
|
||||||
else if (::strncmp(buffer, "[TFT Serial]", 12U) == 0)
|
else if (::strncmp(buffer, "[TFT Serial]", 12U) == 0)
|
||||||
section = SECTION_TFTSERIAL;
|
section = SECTION::TFTSERIAL;
|
||||||
else if (::strncmp(buffer, "[HD44780]", 9U) == 0)
|
else if (::strncmp(buffer, "[HD44780]", 9U) == 0)
|
||||||
section = SECTION_HD44780;
|
section = SECTION::HD44780;
|
||||||
else if (::strncmp(buffer, "[Nextion]", 9U) == 0)
|
else if (::strncmp(buffer, "[Nextion]", 9U) == 0)
|
||||||
section = SECTION_NEXTION;
|
section = SECTION::NEXTION;
|
||||||
else if (::strncmp(buffer, "[OLED]", 6U) == 0)
|
else if (::strncmp(buffer, "[OLED]", 6U) == 0)
|
||||||
section = SECTION_OLED;
|
section = SECTION::OLED;
|
||||||
else if (::strncmp(buffer, "[LCDproc]", 9U) == 0)
|
else if (::strncmp(buffer, "[LCDproc]", 9U) == 0)
|
||||||
section = SECTION_LCDPROC;
|
section = SECTION::LCDPROC;
|
||||||
else if (::strncmp(buffer, "[Lock File]", 11U) == 0)
|
else if (::strncmp(buffer, "[Lock File]", 11U) == 0)
|
||||||
section = SECTION_LOCK_FILE;
|
section = SECTION::LOCK_FILE;
|
||||||
else if (::strncmp(buffer, "[Remote Control]", 16U) == 0)
|
else if (::strncmp(buffer, "[Remote Control]", 16U) == 0)
|
||||||
section = SECTION_REMOTE_CONTROL;
|
section = SECTION::REMOTE_CONTROL;
|
||||||
else
|
else
|
||||||
section = SECTION_NONE;
|
section = SECTION::NONE;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -466,7 +466,7 @@ bool CConf::read()
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section == SECTION_GENERAL) {
|
if (section == SECTION::GENERAL) {
|
||||||
if (::strcmp(key, "Callsign") == 0) {
|
if (::strcmp(key, "Callsign") == 0) {
|
||||||
// Convert the callsign to upper case
|
// Convert the callsign to upper case
|
||||||
for (unsigned int i = 0U; value[i] != 0; i++)
|
for (unsigned int i = 0U; value[i] != 0; i++)
|
||||||
|
|
@ -489,7 +489,7 @@ bool CConf::read()
|
||||||
m_display = value;
|
m_display = value;
|
||||||
else if (::strcmp(key, "Daemon") == 0)
|
else if (::strcmp(key, "Daemon") == 0)
|
||||||
m_daemon = ::atoi(value) == 1;
|
m_daemon = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_INFO) {
|
} else if (section == SECTION::INFO) {
|
||||||
if (::strcmp(key, "TXFrequency") == 0)
|
if (::strcmp(key, "TXFrequency") == 0)
|
||||||
m_pocsagFrequency = m_txFrequency = (unsigned int)::atoi(value);
|
m_pocsagFrequency = m_txFrequency = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "RXFrequency") == 0)
|
else if (::strcmp(key, "RXFrequency") == 0)
|
||||||
|
|
@ -508,7 +508,7 @@ bool CConf::read()
|
||||||
m_description = value;
|
m_description = value;
|
||||||
else if (::strcmp(key, "URL") == 0)
|
else if (::strcmp(key, "URL") == 0)
|
||||||
m_url = value;
|
m_url = value;
|
||||||
} else if (section == SECTION_LOG) {
|
} else if (section == SECTION::LOG) {
|
||||||
if (::strcmp(key, "FilePath") == 0)
|
if (::strcmp(key, "FilePath") == 0)
|
||||||
m_logFilePath = value;
|
m_logFilePath = value;
|
||||||
else if (::strcmp(key, "FileRoot") == 0)
|
else if (::strcmp(key, "FileRoot") == 0)
|
||||||
|
|
@ -519,7 +519,7 @@ bool CConf::read()
|
||||||
m_logDisplayLevel = (unsigned int)::atoi(value);
|
m_logDisplayLevel = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "FileRotate") == 0)
|
else if (::strcmp(key, "FileRotate") == 0)
|
||||||
m_logFileRotate = ::atoi(value) == 1;
|
m_logFileRotate = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_CWID) {
|
} else if (section == SECTION::CWID) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_cwIdEnabled = ::atoi(value) == 1;
|
m_cwIdEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Time") == 0)
|
else if (::strcmp(key, "Time") == 0)
|
||||||
|
|
@ -530,17 +530,17 @@ bool CConf::read()
|
||||||
value[i] = ::toupper(value[i]);
|
value[i] = ::toupper(value[i]);
|
||||||
m_cwIdCallsign = value;
|
m_cwIdCallsign = value;
|
||||||
}
|
}
|
||||||
} else if (section == SECTION_DMRID_LOOKUP) {
|
} else if (section == SECTION::DMRID_LOOKUP) {
|
||||||
if (::strcmp(key, "File") == 0)
|
if (::strcmp(key, "File") == 0)
|
||||||
m_dmrIdLookupFile = value;
|
m_dmrIdLookupFile = value;
|
||||||
else if (::strcmp(key, "Time") == 0)
|
else if (::strcmp(key, "Time") == 0)
|
||||||
m_dmrIdLookupTime = (unsigned int)::atoi(value);
|
m_dmrIdLookupTime = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_NXDNID_LOOKUP) {
|
} else if (section == SECTION::NXDNID_LOOKUP) {
|
||||||
if (::strcmp(key, "File") == 0)
|
if (::strcmp(key, "File") == 0)
|
||||||
m_nxdnIdLookupFile = value;
|
m_nxdnIdLookupFile = value;
|
||||||
else if (::strcmp(key, "Time") == 0)
|
else if (::strcmp(key, "Time") == 0)
|
||||||
m_nxdnIdLookupTime = (unsigned int)::atoi(value);
|
m_nxdnIdLookupTime = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_MODEM) {
|
} else if (section == SECTION::MODEM) {
|
||||||
if (::strcmp(key, "Protocol") == 0)
|
if (::strcmp(key, "Protocol") == 0)
|
||||||
m_modemProtocol = value;
|
m_modemProtocol = value;
|
||||||
else if (::strcmp(key, "UARTPort") == 0)
|
else if (::strcmp(key, "UARTPort") == 0)
|
||||||
|
|
@ -611,7 +611,7 @@ bool CConf::read()
|
||||||
m_modemTrace = ::atoi(value) == 1;
|
m_modemTrace = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_modemDebug = ::atoi(value) == 1;
|
m_modemDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_TRANSPARENT) {
|
} else if (section == SECTION::TRANSPARENT) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_transparentEnabled = ::atoi(value) == 1;
|
m_transparentEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "RemoteAddress") == 0)
|
else if (::strcmp(key, "RemoteAddress") == 0)
|
||||||
|
|
@ -622,7 +622,7 @@ bool CConf::read()
|
||||||
m_transparentLocalPort = (unsigned short)::atoi(value);
|
m_transparentLocalPort = (unsigned short)::atoi(value);
|
||||||
else if (::strcmp(key, "SendFrameType") == 0)
|
else if (::strcmp(key, "SendFrameType") == 0)
|
||||||
m_transparentSendFrameType = (unsigned int)::atoi(value);
|
m_transparentSendFrameType = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_DSTAR) {
|
} else if (section == SECTION::DSTAR) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_dstarEnabled = ::atoi(value) == 1;
|
m_dstarEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Module") == 0) {
|
else if (::strcmp(key, "Module") == 0) {
|
||||||
|
|
@ -661,22 +661,22 @@ bool CConf::read()
|
||||||
else if (::strcmp(key, "AckTime") == 0)
|
else if (::strcmp(key, "AckTime") == 0)
|
||||||
m_dstarAckTime = (unsigned int)::atoi(value);
|
m_dstarAckTime = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "AckMessage") == 0) {
|
else if (::strcmp(key, "AckMessage") == 0) {
|
||||||
m_dstarAckMessage = (DSTAR_ACK_MESSAGE)::atoi(value);
|
m_dstarAckMessage = DSTAR_ACK(::atoi(value));
|
||||||
if (m_dstarAckMessage != DSTAR_ACK_BER && m_dstarAckMessage != DSTAR_ACK_RSSI && m_dstarAckMessage != DSTAR_ACK_SMETER)
|
if ((m_dstarAckMessage != DSTAR_ACK::BER) && (m_dstarAckMessage != DSTAR_ACK::RSSI) && (m_dstarAckMessage != DSTAR_ACK::SMETER))
|
||||||
m_dstarAckMessage = DSTAR_ACK_BER;
|
m_dstarAckMessage = DSTAR_ACK::BER;
|
||||||
} else if (::strcmp(key, "ErrorReply") == 0)
|
} else if (::strcmp(key, "ErrorReply") == 0)
|
||||||
m_dstarErrorReply = ::atoi(value) == 1;
|
m_dstarErrorReply = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "RemoteGateway") == 0)
|
else if (::strcmp(key, "RemoteGateway") == 0)
|
||||||
m_dstarRemoteGateway = ::atoi(value) == 1;
|
m_dstarRemoteGateway = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_dstarModeHang = (unsigned int)::atoi(value);
|
m_dstarModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_DMR) {
|
} else if (section == SECTION::DMR) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_dmrEnabled = ::atoi(value) == 1;
|
m_dmrEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Beacons") == 0)
|
else if (::strcmp(key, "Beacons") == 0)
|
||||||
m_dmrBeacons = ::atoi(value) == 1 ? DMR_BEACONS_NETWORK : DMR_BEACONS_OFF;
|
m_dmrBeacons = ::atoi(value) == 1 ? DMR_BEACONS::NETWORK : DMR_BEACONS::OFF;
|
||||||
else if (::strcmp(key, "BeaconInterval") == 0) {
|
else if (::strcmp(key, "BeaconInterval") == 0) {
|
||||||
m_dmrBeacons = m_dmrBeacons != DMR_BEACONS_OFF ? DMR_BEACONS_TIMED : DMR_BEACONS_OFF;
|
m_dmrBeacons = m_dmrBeacons != DMR_BEACONS::OFF ? DMR_BEACONS::TIMED : DMR_BEACONS::OFF;
|
||||||
m_dmrBeaconInterval = (unsigned int)::atoi(value);
|
m_dmrBeaconInterval = (unsigned int)::atoi(value);
|
||||||
} else if (::strcmp(key, "BeaconDuration") == 0)
|
} else if (::strcmp(key, "BeaconDuration") == 0)
|
||||||
m_dmrBeaconDuration = (unsigned int)::atoi(value);
|
m_dmrBeaconDuration = (unsigned int)::atoi(value);
|
||||||
|
|
@ -739,24 +739,24 @@ bool CConf::read()
|
||||||
else if (::strcmp(key, "OVCM") == 0) {
|
else if (::strcmp(key, "OVCM") == 0) {
|
||||||
switch (::atoi(value)) {
|
switch (::atoi(value)) {
|
||||||
case 1:
|
case 1:
|
||||||
m_dmrOVCM = DMR_OVCM_RX_ON;
|
m_dmrOVCM = DMR_OVCM::RX_ON;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_dmrOVCM = DMR_OVCM_TX_ON;
|
m_dmrOVCM = DMR_OVCM::TX_ON;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
m_dmrOVCM = DMR_OVCM_ON;
|
m_dmrOVCM = DMR_OVCM::ON;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
m_dmrOVCM = DMR_OVCM_FORCE_OFF;
|
m_dmrOVCM = DMR_OVCM::FORCE_OFF;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_dmrOVCM = DMR_OVCM_OFF;
|
m_dmrOVCM = DMR_OVCM::OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (::strcmp(key, "Protect") == 0)
|
} else if (::strcmp(key, "Protect") == 0)
|
||||||
m_dmrProtect = ::atoi(value) == 1;
|
m_dmrProtect = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_FUSION) {
|
} else if (section == SECTION::FUSION) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_fusionEnabled = ::atoi(value) == 1;
|
m_fusionEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "LowDeviation") == 0)
|
else if (::strcmp(key, "LowDeviation") == 0)
|
||||||
|
|
@ -769,7 +769,7 @@ bool CConf::read()
|
||||||
m_fusionTXHang = (unsigned int)::atoi(value);
|
m_fusionTXHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_fusionModeHang = (unsigned int)::atoi(value);
|
m_fusionModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_P25) {
|
} else if (section == SECTION::P25) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_p25Enabled = ::atoi(value) == 1;
|
m_p25Enabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Id") == 0)
|
else if (::strcmp(key, "Id") == 0)
|
||||||
|
|
@ -786,7 +786,7 @@ bool CConf::read()
|
||||||
m_p25TXHang = (unsigned int)::atoi(value);
|
m_p25TXHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_p25ModeHang = (unsigned int)::atoi(value);
|
m_p25ModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_NXDN) {
|
} else if (section == SECTION::NXDN) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_nxdnEnabled = ::atoi(value) == 1;
|
m_nxdnEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Id") == 0)
|
else if (::strcmp(key, "Id") == 0)
|
||||||
|
|
@ -801,7 +801,7 @@ bool CConf::read()
|
||||||
m_nxdnTXHang = (unsigned int)::atoi(value);
|
m_nxdnTXHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_nxdnModeHang = (unsigned int)::atoi(value);
|
m_nxdnModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_M17) {
|
} else if (section == SECTION::M17) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_m17Enabled = ::atoi(value) == 1;
|
m_m17Enabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "CAN") == 0)
|
else if (::strcmp(key, "CAN") == 0)
|
||||||
|
|
@ -814,12 +814,12 @@ bool CConf::read()
|
||||||
m_m17TXHang = (unsigned int)::atoi(value);
|
m_m17TXHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_m17ModeHang = (unsigned int)::atoi(value);
|
m_m17ModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_POCSAG) {
|
} else if (section == SECTION::POCSAG) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_pocsagEnabled = ::atoi(value) == 1;
|
m_pocsagEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Frequency") == 0)
|
else if (::strcmp(key, "Frequency") == 0)
|
||||||
m_pocsagFrequency = (unsigned int)::atoi(value);
|
m_pocsagFrequency = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_FM) {
|
} else if (section == SECTION::FM) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_fmEnabled = ::atoi(value) == 1;
|
m_fmEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Callsign") == 0) {
|
else if (::strcmp(key, "Callsign") == 0) {
|
||||||
|
|
@ -905,7 +905,7 @@ bool CConf::read()
|
||||||
m_fmExtAudioBoost = (unsigned int)::atoi(value);
|
m_fmExtAudioBoost = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_fmModeHang = (unsigned int)::atoi(value);
|
m_fmModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_AX25) {
|
} else if (section == SECTION::AX25) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_ax25Enabled = ::atoi(value) == 1;
|
m_ax25Enabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "TXDelay") == 0)
|
else if (::strcmp(key, "TXDelay") == 0)
|
||||||
|
|
@ -918,7 +918,7 @@ bool CConf::read()
|
||||||
m_ax25PPersist = (unsigned int)::atoi(value);
|
m_ax25PPersist = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Trace") == 0)
|
else if (::strcmp(key, "Trace") == 0)
|
||||||
m_ax25Trace = ::atoi(value) == 1;
|
m_ax25Trace = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_DSTAR_NETWORK) {
|
} else if (section == SECTION::DSTAR_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_dstarNetworkEnabled = ::atoi(value) == 1;
|
m_dstarNetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "GatewayAddress") == 0)
|
else if (::strcmp(key, "GatewayAddress") == 0)
|
||||||
|
|
@ -933,7 +933,7 @@ bool CConf::read()
|
||||||
m_dstarNetworkModeHang = (unsigned int)::atoi(value);
|
m_dstarNetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_dstarNetworkDebug = ::atoi(value) == 1;
|
m_dstarNetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_DMR_NETWORK) {
|
} else if (section == SECTION::DMR_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_dmrNetworkEnabled = ::atoi(value) == 1;
|
m_dmrNetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Type") == 0)
|
else if (::strcmp(key, "Type") == 0)
|
||||||
|
|
@ -960,7 +960,7 @@ bool CConf::read()
|
||||||
m_dmrNetworkSlot2 = ::atoi(value) == 1;
|
m_dmrNetworkSlot2 = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "ModeHang") == 0)
|
else if (::strcmp(key, "ModeHang") == 0)
|
||||||
m_dmrNetworkModeHang = (unsigned int)::atoi(value);
|
m_dmrNetworkModeHang = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_FUSION_NETWORK) {
|
} else if (section == SECTION::FUSION_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_fusionNetworkEnabled = ::atoi(value) == 1;
|
m_fusionNetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "LocalAddress") == 0)
|
else if (::strcmp(key, "LocalAddress") == 0)
|
||||||
|
|
@ -975,7 +975,7 @@ bool CConf::read()
|
||||||
m_fusionNetworkModeHang = (unsigned int)::atoi(value);
|
m_fusionNetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_fusionNetworkDebug = ::atoi(value) == 1;
|
m_fusionNetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_P25_NETWORK) {
|
} else if (section == SECTION::P25_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_p25NetworkEnabled = ::atoi(value) == 1;
|
m_p25NetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "GatewayAddress") == 0)
|
else if (::strcmp(key, "GatewayAddress") == 0)
|
||||||
|
|
@ -990,7 +990,7 @@ bool CConf::read()
|
||||||
m_p25NetworkModeHang = (unsigned int)::atoi(value);
|
m_p25NetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_p25NetworkDebug = ::atoi(value) == 1;
|
m_p25NetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_NXDN_NETWORK) {
|
} else if (section == SECTION::NXDN_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_nxdnNetworkEnabled = ::atoi(value) == 1;
|
m_nxdnNetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "LocalAddress") == 0)
|
else if (::strcmp(key, "LocalAddress") == 0)
|
||||||
|
|
@ -1005,7 +1005,7 @@ bool CConf::read()
|
||||||
m_nxdnNetworkModeHang = (unsigned int)::atoi(value);
|
m_nxdnNetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_nxdnNetworkDebug = ::atoi(value) == 1;
|
m_nxdnNetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_M17_NETWORK) {
|
} else if (section == SECTION::M17_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_m17NetworkEnabled = ::atoi(value) == 1;
|
m_m17NetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "LocalAddress") == 0)
|
else if (::strcmp(key, "LocalAddress") == 0)
|
||||||
|
|
@ -1020,7 +1020,7 @@ bool CConf::read()
|
||||||
m_m17NetworkModeHang = (unsigned int)::atoi(value);
|
m_m17NetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_m17NetworkDebug = ::atoi(value) == 1;
|
m_m17NetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_POCSAG_NETWORK) {
|
} else if (section == SECTION::POCSAG_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_pocsagNetworkEnabled = ::atoi(value) == 1;
|
m_pocsagNetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "LocalAddress") == 0)
|
else if (::strcmp(key, "LocalAddress") == 0)
|
||||||
|
|
@ -1035,7 +1035,7 @@ bool CConf::read()
|
||||||
m_pocsagNetworkModeHang = (unsigned int)::atoi(value);
|
m_pocsagNetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_pocsagNetworkDebug = ::atoi(value) == 1;
|
m_pocsagNetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_FM_NETWORK) {
|
} else if (section == SECTION::FM_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_fmNetworkEnabled = ::atoi(value) == 1;
|
m_fmNetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Protocol") == 0)
|
else if (::strcmp(key, "Protocol") == 0)
|
||||||
|
|
@ -1064,7 +1064,7 @@ bool CConf::read()
|
||||||
m_fmNetworkModeHang = (unsigned int)::atoi(value);
|
m_fmNetworkModeHang = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_fmNetworkDebug = ::atoi(value) == 1;
|
m_fmNetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_AX25_NETWORK) {
|
} else if (section == SECTION::AX25_NETWORK) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_ax25NetworkEnabled = ::atoi(value) == 1;
|
m_ax25NetworkEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Port") == 0)
|
else if (::strcmp(key, "Port") == 0)
|
||||||
|
|
@ -1073,14 +1073,14 @@ bool CConf::read()
|
||||||
m_ax25NetworkSpeed = (unsigned int)::atoi(value);
|
m_ax25NetworkSpeed = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Debug") == 0)
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
m_ax25NetworkDebug = ::atoi(value) == 1;
|
m_ax25NetworkDebug = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_TFTSERIAL) {
|
} else if (section == SECTION::TFTSERIAL) {
|
||||||
if (::strcmp(key, "Port") == 0)
|
if (::strcmp(key, "Port") == 0)
|
||||||
m_tftSerialPort = value;
|
m_tftSerialPort = value;
|
||||||
else if (::strcmp(key, "Brightness") == 0)
|
else if (::strcmp(key, "Brightness") == 0)
|
||||||
m_tftSerialBrightness = (unsigned int)::atoi(value);
|
m_tftSerialBrightness = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "ScreenLayout") == 0)
|
else if (::strcmp(key, "ScreenLayout") == 0)
|
||||||
m_tftSerialScreenLayout = (unsigned int)::atoi(value);
|
m_tftSerialScreenLayout = (unsigned int)::atoi(value);
|
||||||
} else if (section == SECTION_HD44780) {
|
} else if (section == SECTION::HD44780) {
|
||||||
if (::strcmp(key, "Rows") == 0)
|
if (::strcmp(key, "Rows") == 0)
|
||||||
m_hd44780Rows = (unsigned int)::atoi(value);
|
m_hd44780Rows = (unsigned int)::atoi(value);
|
||||||
else if (::strcmp(key, "Columns") == 0)
|
else if (::strcmp(key, "Columns") == 0)
|
||||||
|
|
@ -1107,7 +1107,7 @@ bool CConf::read()
|
||||||
p = ::strtok(NULL, ",\r\n");
|
p = ::strtok(NULL, ",\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (section == SECTION_NEXTION) {
|
} else if (section == SECTION::NEXTION) {
|
||||||
if (::strcmp(key, "Port") == 0)
|
if (::strcmp(key, "Port") == 0)
|
||||||
m_nextionPort = value;
|
m_nextionPort = value;
|
||||||
else if (::strcmp(key, "Brightness") == 0)
|
else if (::strcmp(key, "Brightness") == 0)
|
||||||
|
|
@ -1126,7 +1126,7 @@ bool CConf::read()
|
||||||
m_nextionOutput = ::atoi(value) == 1;
|
m_nextionOutput = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "NextionUDPPort") == 0)
|
else if (::strcmp(key, "NextionUDPPort") == 0)
|
||||||
m_nextionUDPPort = (unsigned short)::atoi(value);
|
m_nextionUDPPort = (unsigned short)::atoi(value);
|
||||||
} else if (section == SECTION_OLED) {
|
} else if (section == SECTION::OLED) {
|
||||||
if (::strcmp(key, "Type") == 0)
|
if (::strcmp(key, "Type") == 0)
|
||||||
m_oledType = (unsigned char)::atoi(value);
|
m_oledType = (unsigned char)::atoi(value);
|
||||||
else if (::strcmp(key, "Brightness") == 0)
|
else if (::strcmp(key, "Brightness") == 0)
|
||||||
|
|
@ -1139,7 +1139,7 @@ bool CConf::read()
|
||||||
m_oledRotate = ::atoi(value) == 1;
|
m_oledRotate = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "LogoScreensaver") == 0)
|
else if (::strcmp(key, "LogoScreensaver") == 0)
|
||||||
m_oledLogoScreensaver = ::atoi(value) == 1;
|
m_oledLogoScreensaver = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_LCDPROC) {
|
} else if (section == SECTION::LCDPROC) {
|
||||||
if (::strcmp(key, "Address") == 0)
|
if (::strcmp(key, "Address") == 0)
|
||||||
m_lcdprocAddress = value;
|
m_lcdprocAddress = value;
|
||||||
else if (::strcmp(key, "Port") == 0)
|
else if (::strcmp(key, "Port") == 0)
|
||||||
|
|
@ -1152,12 +1152,12 @@ bool CConf::read()
|
||||||
m_lcdprocUTC = ::atoi(value) == 1;
|
m_lcdprocUTC = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "DimOnIdle") == 0)
|
else if (::strcmp(key, "DimOnIdle") == 0)
|
||||||
m_lcdprocDimOnIdle = ::atoi(value) == 1;
|
m_lcdprocDimOnIdle = ::atoi(value) == 1;
|
||||||
} else if (section == SECTION_LOCK_FILE) {
|
} else if (section == SECTION::LOCK_FILE) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_lockFileEnabled = ::atoi(value) == 1;
|
m_lockFileEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "File") == 0)
|
else if (::strcmp(key, "File") == 0)
|
||||||
m_lockFileName = value;
|
m_lockFileName = value;
|
||||||
} else if (section == SECTION_REMOTE_CONTROL) {
|
} else if (section == SECTION::REMOTE_CONTROL) {
|
||||||
if (::strcmp(key, "Enable") == 0)
|
if (::strcmp(key, "Enable") == 0)
|
||||||
m_remoteControlEnabled = ::atoi(value) == 1;
|
m_remoteControlEnabled = ::atoi(value) == 1;
|
||||||
else if (::strcmp(key, "Port") == 0)
|
else if (::strcmp(key, "Port") == 0)
|
||||||
|
|
@ -1535,7 +1535,7 @@ unsigned int CConf::getDStarAckTime() const
|
||||||
return m_dstarAckTime;
|
return m_dstarAckTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSTAR_ACK_MESSAGE CConf::getDStarAckMessage() const
|
DSTAR_ACK CConf::getDStarAckMessage() const
|
||||||
{
|
{
|
||||||
return m_dstarAckMessage;
|
return m_dstarAckMessage;
|
||||||
}
|
}
|
||||||
|
|
@ -1640,7 +1640,7 @@ unsigned int CConf::getDMRModeHang() const
|
||||||
return m_dmrModeHang;
|
return m_dmrModeHang;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMR_OVCM_TYPES CConf::getDMROVCM() const
|
DMR_OVCM CConf::getDMROVCM() const
|
||||||
{
|
{
|
||||||
return m_dmrOVCM;
|
return m_dmrOVCM;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
Conf.h
10
Conf.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2023 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2023,2025 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
|
||||||
|
|
@ -120,7 +120,7 @@ public:
|
||||||
std::vector<std::string> getDStarWhiteList() const;
|
std::vector<std::string> getDStarWhiteList() const;
|
||||||
bool getDStarAckReply() const;
|
bool getDStarAckReply() const;
|
||||||
unsigned int getDStarAckTime() const;
|
unsigned int getDStarAckTime() const;
|
||||||
DSTAR_ACK_MESSAGE getDStarAckMessage() const;
|
DSTAR_ACK getDStarAckMessage() const;
|
||||||
bool getDStarErrorReply() const;
|
bool getDStarErrorReply() const;
|
||||||
bool getDStarRemoteGateway() const;
|
bool getDStarRemoteGateway() const;
|
||||||
unsigned int getDStarModeHang() const;
|
unsigned int getDStarModeHang() const;
|
||||||
|
|
@ -143,7 +143,7 @@ public:
|
||||||
unsigned int getDMRCallHang() const;
|
unsigned int getDMRCallHang() const;
|
||||||
unsigned int getDMRTXHang() const;
|
unsigned int getDMRTXHang() const;
|
||||||
unsigned int getDMRModeHang() const;
|
unsigned int getDMRModeHang() const;
|
||||||
DMR_OVCM_TYPES getDMROVCM() const;
|
DMR_OVCM getDMROVCM() const;
|
||||||
bool getDMRProtect() const;
|
bool getDMRProtect() const;
|
||||||
|
|
||||||
// The System Fusion section
|
// The System Fusion section
|
||||||
|
|
@ -459,7 +459,7 @@ private:
|
||||||
std::vector<std::string> m_dstarWhiteList;
|
std::vector<std::string> m_dstarWhiteList;
|
||||||
bool m_dstarAckReply;
|
bool m_dstarAckReply;
|
||||||
unsigned int m_dstarAckTime;
|
unsigned int m_dstarAckTime;
|
||||||
DSTAR_ACK_MESSAGE m_dstarAckMessage;
|
DSTAR_ACK m_dstarAckMessage;
|
||||||
bool m_dstarErrorReply;
|
bool m_dstarErrorReply;
|
||||||
bool m_dstarRemoteGateway;
|
bool m_dstarRemoteGateway;
|
||||||
unsigned int m_dstarModeHang;
|
unsigned int m_dstarModeHang;
|
||||||
|
|
@ -481,7 +481,7 @@ private:
|
||||||
unsigned int m_dmrCallHang;
|
unsigned int m_dmrCallHang;
|
||||||
unsigned int m_dmrTXHang;
|
unsigned int m_dmrTXHang;
|
||||||
unsigned int m_dmrModeHang;
|
unsigned int m_dmrModeHang;
|
||||||
DMR_OVCM_TYPES m_dmrOVCM;
|
DMR_OVCM m_dmrOVCM;
|
||||||
bool m_dmrProtect;
|
bool m_dmrProtect;
|
||||||
|
|
||||||
bool m_fusionEnabled;
|
bool m_fusionEnabled;
|
||||||
|
|
|
||||||
24
DMRCSBK.cpp
24
DMRCSBK.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2020,2021,2022 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020,2021,2022,2025 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2019 by Patrick Maier DK5MP
|
* Copyright (C) 2019 by Patrick Maier DK5MP
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
CDMRCSBK::CDMRCSBK() :
|
CDMRCSBK::CDMRCSBK() :
|
||||||
m_data(NULL),
|
m_data(NULL),
|
||||||
m_CSBKO(CSBKO_NONE),
|
m_CSBKO(CSBKO::NONE),
|
||||||
m_FID(0x00U),
|
m_FID(0x00U),
|
||||||
m_GI(false),
|
m_GI(false),
|
||||||
m_bsId(0U),
|
m_bsId(0U),
|
||||||
|
|
@ -67,7 +67,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
m_FID = m_data[1U];
|
m_FID = m_data[1U];
|
||||||
|
|
||||||
switch (m_CSBKO) {
|
switch (m_CSBKO) {
|
||||||
case CSBKO_BSDWNACT:
|
case CSBKO::BSDWNACT:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_bsId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_bsId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -76,7 +76,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Downlink Activate CSBK", m_data, 12U);
|
CUtils::dump(1U, "Downlink Activate CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_UUVREQ:
|
case CSBKO::UUVREQ:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -86,7 +86,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Unit to Unit Service Request CSBK", m_data, 12U);
|
CUtils::dump(1U, "Unit to Unit Service Request CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_UUANSRSP:
|
case CSBKO::UUANSRSP:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -96,7 +96,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Unit to Unit Service Answer Response CSBK", m_data, 12U);
|
CUtils::dump(1U, "Unit to Unit Service Answer Response CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_PRECCSBK:
|
case CSBKO::PRECCSBK:
|
||||||
m_GI = (m_data[2U] & 0x40U) == 0x40U;
|
m_GI = (m_data[2U] & 0x40U) == 0x40U;
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -105,7 +105,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Preamble CSBK", m_data, 12U);
|
CUtils::dump(1U, "Preamble CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_NACKRSP:
|
case CSBKO::NACKRSP:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_srcId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_srcId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_dstId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_dstId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -114,7 +114,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Negative Acknowledge Response CSBK", m_data, 12U);
|
CUtils::dump(1U, "Negative Acknowledge Response CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_CALL_ALERT:
|
case CSBKO::CALL_ALERT:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -123,7 +123,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Call Alert CSBK", m_data, 12U);
|
CUtils::dump(1U, "Call Alert CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_CALL_ALERT_ACK:
|
case CSBKO::CALL_ALERT_ACK:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -132,7 +132,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Call Alert Ack CSBK", m_data, 12U);
|
CUtils::dump(1U, "Call Alert Ack CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_RADIO_CHECK:
|
case CSBKO::RADIO_CHECK:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
if (m_data[3U] == 0x80) {
|
if (m_data[3U] == 0x80) {
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
|
|
@ -147,7 +147,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
m_CBF = 0U;
|
m_CBF = 0U;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSBKO_CALL_EMERGENCY:
|
case CSBKO::CALL_EMERGENCY:
|
||||||
m_GI = true;
|
m_GI = true;
|
||||||
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
|
@ -202,7 +202,7 @@ bool CDMRCSBK::getOVCM() const
|
||||||
|
|
||||||
void CDMRCSBK::setOVCM(bool ovcm)
|
void CDMRCSBK::setOVCM(bool ovcm)
|
||||||
{
|
{
|
||||||
if (m_CSBKO == CSBKO_UUVREQ || m_CSBKO == CSBKO_UUANSRSP) {
|
if ((m_CSBKO == CSBKO::UUVREQ) || (m_CSBKO == CSBKO::UUANSRSP)) {
|
||||||
m_OVCM = ovcm;
|
m_OVCM = ovcm;
|
||||||
|
|
||||||
if (ovcm)
|
if (ovcm)
|
||||||
|
|
|
||||||
26
DMRCSBK.h
26
DMRCSBK.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2020,2021,2022 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020,2021,2022,2025 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
|
||||||
|
|
@ -21,18 +21,18 @@
|
||||||
|
|
||||||
#include "DMRDefines.h"
|
#include "DMRDefines.h"
|
||||||
|
|
||||||
enum CSBKO {
|
enum class CSBKO {
|
||||||
CSBKO_NONE = 0x00,
|
NONE = 0x00,
|
||||||
CSBKO_UUVREQ = 0x04,
|
UUVREQ = 0x04,
|
||||||
CSBKO_UUANSRSP = 0x05,
|
UUANSRSP = 0x05,
|
||||||
CSBKO_CTCSBK = 0x07,
|
CTCSBK = 0x07,
|
||||||
CSBKO_CALL_ALERT = 0x1F,
|
CALL_ALERT = 0x1F,
|
||||||
CSBKO_CALL_ALERT_ACK = 0x20,
|
CALL_ALERT_ACK = 0x20,
|
||||||
CSBKO_RADIO_CHECK = 0x24,
|
RADIO_CHECK = 0x24,
|
||||||
CSBKO_NACKRSP = 0x26,
|
NACKRSP = 0x26,
|
||||||
CSBKO_CALL_EMERGENCY = 0x27,
|
CALL_EMERGENCY = 0x27,
|
||||||
CSBKO_BSDWNACT = 0x38,
|
BSDWNACT = 0x38,
|
||||||
CSBKO_PRECCSBK = 0x3D
|
PRECCSBK = 0x3D
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDMRCSBK
|
class CDMRCSBK
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015-2021,2025 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
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect) :
|
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM ovcm, bool protect) :
|
||||||
m_colorCode(colorCode),
|
m_colorCode(colorCode),
|
||||||
m_modem(modem),
|
m_modem(modem),
|
||||||
m_network(network),
|
m_network(network),
|
||||||
|
|
@ -59,7 +59,7 @@ bool CDMRControl::processWakeup(const unsigned char* data)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CSBKO csbko = csbk.getCSBKO();
|
CSBKO csbko = csbk.getCSBKO();
|
||||||
if (csbko != CSBKO_BSDWNACT)
|
if (csbko != CSBKO::BSDWNACT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int srcId = csbk.getSrcId();
|
unsigned int srcId = csbk.getSrcId();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021,2025 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,7 +31,7 @@
|
||||||
|
|
||||||
class CDMRControl {
|
class CDMRControl {
|
||||||
public:
|
public:
|
||||||
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect);
|
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM ovcm, bool protect);
|
||||||
~CDMRControl();
|
~CDMRControl();
|
||||||
|
|
||||||
bool processWakeup(const unsigned char* data);
|
bool processWakeup(const unsigned char* data);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015,2016,2017,2025 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
|
||||||
|
|
@ -42,7 +42,7 @@ m_slotNo(1U),
|
||||||
m_data(NULL),
|
m_data(NULL),
|
||||||
m_srcId(0U),
|
m_srcId(0U),
|
||||||
m_dstId(0U),
|
m_dstId(0U),
|
||||||
m_flco(FLCO_GROUP),
|
m_flco(FLCO::GROUP),
|
||||||
m_dataType(0U),
|
m_dataType(0U),
|
||||||
m_seqNo(0U),
|
m_seqNo(0U),
|
||||||
m_n(0U),
|
m_n(0U),
|
||||||
|
|
|
||||||
18
DMRDefines.h
18
DMRDefines.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2021,2025 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
|
||||||
|
|
@ -110,14 +110,14 @@ const unsigned char DPF_PROPRIETARY = 0x0FU;
|
||||||
const unsigned char FID_ETSI = 0U;
|
const unsigned char FID_ETSI = 0U;
|
||||||
const unsigned char FID_DMRA = 16U;
|
const unsigned char FID_DMRA = 16U;
|
||||||
|
|
||||||
enum FLCO {
|
enum class FLCO {
|
||||||
FLCO_GROUP = 0,
|
GROUP = 0,
|
||||||
FLCO_USER_USER = 3,
|
USER_USER = 3,
|
||||||
FLCO_TALKER_ALIAS_HEADER = 4,
|
TALKER_ALIAS_HEADER = 4,
|
||||||
FLCO_TALKER_ALIAS_BLOCK1 = 5,
|
TALKER_ALIAS_BLOCK1 = 5,
|
||||||
FLCO_TALKER_ALIAS_BLOCK2 = 6,
|
TALKER_ALIAS_BLOCK2 = 6,
|
||||||
FLCO_TALKER_ALIAS_BLOCK3 = 7,
|
TALKER_ALIAS_BLOCK3 = 7,
|
||||||
FLCO_GPS_INFO = 8
|
GINFO = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017,2018,2020,2021,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018,2020,2021,2024,2025 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
|
||||||
|
|
@ -45,7 +45,7 @@ m_enabled(false),
|
||||||
m_slot1(slot1),
|
m_slot1(slot1),
|
||||||
m_slot2(slot2),
|
m_slot2(slot2),
|
||||||
m_hwType(hwType),
|
m_hwType(hwType),
|
||||||
m_status(WAITING_CONNECT),
|
m_status(STATUS::WAITING_CONNECT),
|
||||||
m_retryTimer(1000U, 10U),
|
m_retryTimer(1000U, 10U),
|
||||||
m_timeoutTimer(1000U, 60U),
|
m_timeoutTimer(1000U, 60U),
|
||||||
m_buffer(NULL),
|
m_buffer(NULL),
|
||||||
|
|
@ -131,7 +131,7 @@ bool CDMRDirectNetwork::open()
|
||||||
|
|
||||||
LogMessage("DMR, Opening DMR Network");
|
LogMessage("DMR, Opening DMR Network");
|
||||||
|
|
||||||
m_status = WAITING_CONNECT;
|
m_status = STATUS::WAITING_CONNECT;
|
||||||
m_timeoutTimer.stop();
|
m_timeoutTimer.stop();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
|
|
||||||
|
|
@ -148,7 +148,7 @@ void CDMRDirectNetwork::enable(bool enabled)
|
||||||
|
|
||||||
bool CDMRDirectNetwork::read(CDMRData& data)
|
bool CDMRDirectNetwork::read(CDMRData& data)
|
||||||
{
|
{
|
||||||
if (m_status != RUNNING)
|
if (m_status != STATUS::RUNNING)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_rxData.isEmpty())
|
if (m_rxData.isEmpty())
|
||||||
|
|
@ -180,7 +180,7 @@ bool CDMRDirectNetwork::read(CDMRData& data)
|
||||||
if (slotNo == 2U && !m_slot2)
|
if (slotNo == 2U && !m_slot2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO::USER_USER : FLCO::GROUP;
|
||||||
|
|
||||||
data.setSeqNo(seqNo);
|
data.setSeqNo(seqNo);
|
||||||
data.setSlotNo(slotNo);
|
data.setSlotNo(slotNo);
|
||||||
|
|
@ -212,7 +212,7 @@ bool CDMRDirectNetwork::read(CDMRData& data)
|
||||||
|
|
||||||
bool CDMRDirectNetwork::write(const CDMRData& data)
|
bool CDMRDirectNetwork::write(const CDMRData& data)
|
||||||
{
|
{
|
||||||
if (m_status != RUNNING)
|
if (m_status != STATUS::RUNNING)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||||
|
|
@ -246,7 +246,7 @@ bool CDMRDirectNetwork::write(const CDMRData& data)
|
||||||
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||||
|
|
||||||
FLCO flco = data.getFLCO();
|
FLCO flco = data.getFLCO();
|
||||||
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
buffer[15U] |= flco == FLCO::GROUP ? 0x00U : 0x40U;
|
||||||
|
|
||||||
unsigned int slotIndex = slotNo - 1U;
|
unsigned int slotIndex = slotNo - 1U;
|
||||||
|
|
||||||
|
|
@ -283,7 +283,7 @@ bool CDMRDirectNetwork::write(const CDMRData& data)
|
||||||
|
|
||||||
bool CDMRDirectNetwork::writeRadioPosition(unsigned int id, const unsigned char* data)
|
bool CDMRDirectNetwork::writeRadioPosition(unsigned int id, const unsigned char* data)
|
||||||
{
|
{
|
||||||
if (m_status != RUNNING)
|
if (m_status != STATUS::RUNNING)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char buffer[20U];
|
unsigned char buffer[20U];
|
||||||
|
|
@ -301,7 +301,7 @@ bool CDMRDirectNetwork::writeRadioPosition(unsigned int id, const unsigned char*
|
||||||
|
|
||||||
bool CDMRDirectNetwork::writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data)
|
bool CDMRDirectNetwork::writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data)
|
||||||
{
|
{
|
||||||
if (m_status != RUNNING)
|
if (m_status != STATUS::RUNNING)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char buffer[20U];
|
unsigned char buffer[20U];
|
||||||
|
|
@ -321,14 +321,14 @@ bool CDMRDirectNetwork::writeTalkerAlias(unsigned int id, unsigned char type, co
|
||||||
|
|
||||||
bool CDMRDirectNetwork::isConnected() const
|
bool CDMRDirectNetwork::isConnected() const
|
||||||
{
|
{
|
||||||
return (m_status == RUNNING);
|
return (m_status == STATUS::RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRDirectNetwork::close(bool sayGoodbye)
|
void CDMRDirectNetwork::close(bool sayGoodbye)
|
||||||
{
|
{
|
||||||
LogMessage("DMR, Closing DMR Network");
|
LogMessage("DMR, Closing DMR Network");
|
||||||
|
|
||||||
if (sayGoodbye && (m_status == RUNNING)) {
|
if (sayGoodbye && (m_status == STATUS::RUNNING)) {
|
||||||
unsigned char buffer[9U];
|
unsigned char buffer[9U];
|
||||||
::memcpy(buffer + 0U, "RPTCL", 5U);
|
::memcpy(buffer + 0U, "RPTCL", 5U);
|
||||||
::memcpy(buffer + 5U, m_id, 4U);
|
::memcpy(buffer + 5U, m_id, 4U);
|
||||||
|
|
@ -346,23 +346,23 @@ void CDMRDirectNetwork::clock(unsigned int ms)
|
||||||
m_retryTimer.clock(ms);
|
m_retryTimer.clock(ms);
|
||||||
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
||||||
switch (m_status) {
|
switch (m_status) {
|
||||||
case WAITING_CONNECT:
|
case STATUS::WAITING_CONNECT:
|
||||||
writeLogin();
|
writeLogin();
|
||||||
m_status = WAITING_LOGIN;
|
m_status = STATUS::WAITING_LOGIN;
|
||||||
break;
|
break;
|
||||||
case WAITING_LOGIN:
|
case STATUS::WAITING_LOGIN:
|
||||||
writeLogin();
|
writeLogin();
|
||||||
break;
|
break;
|
||||||
case WAITING_AUTHORISATION:
|
case STATUS::WAITING_AUTHORISATION:
|
||||||
writeAuthorisation();
|
writeAuthorisation();
|
||||||
break;
|
break;
|
||||||
case WAITING_OPTIONS:
|
case STATUS::WAITING_OPTIONS:
|
||||||
writeOptions();
|
writeOptions();
|
||||||
break;
|
break;
|
||||||
case WAITING_CONFIG:
|
case STATUS::WAITING_CONFIG:
|
||||||
writeConfig();
|
writeConfig();
|
||||||
break;
|
break;
|
||||||
case RUNNING:
|
case STATUS::RUNNING:
|
||||||
writePing();
|
writePing();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -398,9 +398,9 @@ void CDMRDirectNetwork::clock(unsigned int ms)
|
||||||
m_rxData.addData(m_buffer, len);
|
m_rxData.addData(m_buffer, len);
|
||||||
}
|
}
|
||||||
} else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) {
|
} else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) {
|
||||||
if (m_status == RUNNING) {
|
if (m_status == STATUS::RUNNING) {
|
||||||
LogWarning("DMR, Login to the master has failed, retrying login ...");
|
LogWarning("DMR, Login to the master has failed, retrying login ...");
|
||||||
m_status = WAITING_LOGIN;
|
m_status = STATUS::WAITING_LOGIN;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -414,36 +414,36 @@ void CDMRDirectNetwork::clock(unsigned int ms)
|
||||||
}
|
}
|
||||||
} else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) {
|
} else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) {
|
||||||
switch (m_status) {
|
switch (m_status) {
|
||||||
case WAITING_LOGIN:
|
case STATUS::WAITING_LOGIN:
|
||||||
LogDebug("DMR, Sending authorisation");
|
LogDebug("DMR, Sending authorisation");
|
||||||
::memcpy(m_salt, m_buffer + 6U, sizeof(uint32_t));
|
::memcpy(m_salt, m_buffer + 6U, sizeof(uint32_t));
|
||||||
writeAuthorisation();
|
writeAuthorisation();
|
||||||
m_status = WAITING_AUTHORISATION;
|
m_status = STATUS::WAITING_AUTHORISATION;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
case WAITING_AUTHORISATION:
|
case STATUS::WAITING_AUTHORISATION:
|
||||||
LogDebug("DMR, Sending configuration");
|
LogDebug("DMR, Sending configuration");
|
||||||
writeConfig();
|
writeConfig();
|
||||||
m_status = WAITING_CONFIG;
|
m_status = STATUS::WAITING_CONFIG;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
case WAITING_CONFIG:
|
case STATUS::WAITING_CONFIG:
|
||||||
if (m_options.empty()) {
|
if (m_options.empty()) {
|
||||||
LogMessage("DMR, Logged into the master successfully");
|
LogMessage("DMR, Logged into the master successfully");
|
||||||
m_status = RUNNING;
|
m_status = STATUS::RUNNING;
|
||||||
} else {
|
} else {
|
||||||
LogDebug("DMR, Sending options");
|
LogDebug("DMR, Sending options");
|
||||||
writeOptions();
|
writeOptions();
|
||||||
m_status = WAITING_OPTIONS;
|
m_status = STATUS::WAITING_OPTIONS;
|
||||||
}
|
}
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
case WAITING_OPTIONS:
|
case STATUS::WAITING_OPTIONS:
|
||||||
LogMessage("DMR, Logged into the master successfully");
|
LogMessage("DMR, Logged into the master successfully");
|
||||||
m_status = RUNNING;
|
m_status = STATUS::RUNNING;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_retryTimer.start();
|
m_retryTimer.start();
|
||||||
break;
|
break;
|
||||||
|
|
@ -526,16 +526,16 @@ bool CDMRDirectNetwork::writeConfig()
|
||||||
slots = '2';
|
slots = '2';
|
||||||
|
|
||||||
switch (m_hwType) {
|
switch (m_hwType) {
|
||||||
case HWT_MMDVM:
|
case HW_TYPE::MMDVM:
|
||||||
software = "MMDVM";
|
software = "MMDVM";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS:
|
case HW_TYPE::MMDVM_HS:
|
||||||
software = "MMDVM_MMDVM_HS";
|
software = "MMDVM_MMDVM_HS";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS_DUAL_HAT:
|
case HW_TYPE::MMDVM_HS_DUAL_HAT:
|
||||||
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
break;
|
break;
|
||||||
case HWT_NANO_HOTSPOT:
|
case HW_TYPE::NANO_HOTSPOT:
|
||||||
software = "MMDVM_Nano_hotSPOT";
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -546,31 +546,31 @@ bool CDMRDirectNetwork::writeConfig()
|
||||||
slots = '4';
|
slots = '4';
|
||||||
|
|
||||||
switch (m_hwType) {
|
switch (m_hwType) {
|
||||||
case HWT_MMDVM:
|
case HW_TYPE::MMDVM:
|
||||||
software = "MMDVM_DMO";
|
software = "MMDVM_DMO";
|
||||||
break;
|
break;
|
||||||
case HWT_DVMEGA:
|
case HW_TYPE::DVMEGA:
|
||||||
software = "MMDVM_DVMega";
|
software = "MMDVM_DVMega";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_ZUMSPOT:
|
case HW_TYPE::MMDVM_ZUMSPOT:
|
||||||
software = "MMDVM_ZUMspot";
|
software = "MMDVM_ZUMspot";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS_HAT:
|
case HW_TYPE::MMDVM_HS_HAT:
|
||||||
software = "MMDVM_MMDVM_HS_Hat";
|
software = "MMDVM_MMDVM_HS_Hat";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS_DUAL_HAT:
|
case HW_TYPE::MMDVM_HS_DUAL_HAT:
|
||||||
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
break;
|
break;
|
||||||
case HWT_NANO_HOTSPOT:
|
case HW_TYPE::NANO_HOTSPOT:
|
||||||
software = "MMDVM_Nano_hotSPOT";
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
break;
|
break;
|
||||||
case HWT_NANO_DV:
|
case HW_TYPE::NANO_DV:
|
||||||
software = "MMDVM_Nano_DV";
|
software = "MMDVM_Nano_DV";
|
||||||
break;
|
break;
|
||||||
case HWT_D2RG_MMDVM_HS:
|
case HW_TYPE::D2RG_MMDVM_HS:
|
||||||
software = "MMDVM_D2RG_MMDVM_HS";
|
software = "MMDVM_D2RG_MMDVM_HS";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS:
|
case HW_TYPE::MMDVM_HS:
|
||||||
software = "MMDVM_MMDVM_HS";
|
software = "MMDVM_MMDVM_HS";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018,2020,2021,2025 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
|
||||||
|
|
@ -75,7 +75,7 @@ private:
|
||||||
bool m_slot2;
|
bool m_slot2;
|
||||||
HW_TYPE m_hwType;
|
HW_TYPE m_hwType;
|
||||||
|
|
||||||
enum STATUS {
|
enum class STATUS {
|
||||||
WAITING_CONNECT,
|
WAITING_CONNECT,
|
||||||
WAITING_LOGIN,
|
WAITING_LOGIN,
|
||||||
WAITING_AUTHORISATION,
|
WAITING_AUTHORISATION,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2025 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
|
||||||
|
|
@ -28,9 +28,9 @@
|
||||||
|
|
||||||
CDMREmbeddedData::CDMREmbeddedData() :
|
CDMREmbeddedData::CDMREmbeddedData() :
|
||||||
m_raw(NULL),
|
m_raw(NULL),
|
||||||
m_state(LCS_NONE),
|
m_state(LC_STATE::NONE),
|
||||||
m_data(NULL),
|
m_data(NULL),
|
||||||
m_FLCO(FLCO_GROUP),
|
m_FLCO(FLCO::GROUP),
|
||||||
m_valid(false)
|
m_valid(false)
|
||||||
{
|
{
|
||||||
m_raw = new bool[128U];
|
m_raw = new bool[128U];
|
||||||
|
|
@ -61,41 +61,41 @@ bool CDMREmbeddedData::addData(const unsigned char* data, unsigned char lcss)
|
||||||
m_raw[a] = rawData[a + 4U];
|
m_raw[a] = rawData[a + 4U];
|
||||||
|
|
||||||
// Show we are ready for the next LC block
|
// Show we are ready for the next LC block
|
||||||
m_state = LCS_FIRST;
|
m_state = LC_STATE::FIRST;
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this the 2nd block of a 4 block embedded LC ?
|
// Is this the 2nd block of a 4 block embedded LC ?
|
||||||
if (lcss == 3U && m_state == LCS_FIRST) {
|
if ((lcss == 3U) && (m_state == LC_STATE::FIRST)) {
|
||||||
for (unsigned int a = 0U; a < 32U; a++)
|
for (unsigned int a = 0U; a < 32U; a++)
|
||||||
m_raw[a + 32U] = rawData[a + 4U];
|
m_raw[a + 32U] = rawData[a + 4U];
|
||||||
|
|
||||||
// Show we are ready for the next LC block
|
// Show we are ready for the next LC block
|
||||||
m_state = LCS_SECOND;
|
m_state = LC_STATE::SECOND;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this the 3rd block of a 4 block embedded LC ?
|
// Is this the 3rd block of a 4 block embedded LC ?
|
||||||
if (lcss == 3U && m_state == LCS_SECOND) {
|
if ((lcss == 3U) && (m_state == LC_STATE::SECOND)) {
|
||||||
for (unsigned int a = 0U; a < 32U; a++)
|
for (unsigned int a = 0U; a < 32U; a++)
|
||||||
m_raw[a + 64U] = rawData[a + 4U];
|
m_raw[a + 64U] = rawData[a + 4U];
|
||||||
|
|
||||||
// Show we are ready for the final LC block
|
// Show we are ready for the final LC block
|
||||||
m_state = LCS_THIRD;
|
m_state = LC_STATE::THIRD;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this the final block of a 4 block embedded LC ?
|
// Is this the final block of a 4 block embedded LC ?
|
||||||
if (lcss == 2U && m_state == LCS_THIRD) {
|
if ((lcss == 2U) && (m_state == LC_STATE::THIRD)) {
|
||||||
for (unsigned int a = 0U; a < 32U; a++)
|
for (unsigned int a = 0U; a < 32U; a++)
|
||||||
m_raw[a + 96U] = rawData[a + 4U];
|
m_raw[a + 96U] = rawData[a + 4U];
|
||||||
|
|
||||||
// Show that we're not ready for any more data
|
// Show that we're not ready for any more data
|
||||||
m_state = LCS_NONE;
|
m_state = LC_STATE::NONE;
|
||||||
|
|
||||||
// Process the complete data block
|
// Process the complete data block
|
||||||
decodeEmbeddedData();
|
decodeEmbeddedData();
|
||||||
|
|
@ -279,7 +279,7 @@ CDMRLC* CDMREmbeddedData::getLC() const
|
||||||
if (!m_valid)
|
if (!m_valid)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (m_FLCO != FLCO_GROUP && m_FLCO != FLCO_USER_USER)
|
if ((m_FLCO != FLCO::GROUP) && (m_FLCO != FLCO::USER_USER))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return new CDMRLC(m_data);
|
return new CDMRLC(m_data);
|
||||||
|
|
@ -297,7 +297,7 @@ FLCO CDMREmbeddedData::getFLCO() const
|
||||||
|
|
||||||
void CDMREmbeddedData::reset()
|
void CDMREmbeddedData::reset()
|
||||||
{
|
{
|
||||||
m_state = LCS_NONE;
|
m_state = LC_STATE::NONE;
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2025 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
|
||||||
|
|
@ -22,11 +22,11 @@
|
||||||
#include "DMRDefines.h"
|
#include "DMRDefines.h"
|
||||||
#include "DMRLC.h"
|
#include "DMRLC.h"
|
||||||
|
|
||||||
enum LC_STATE {
|
enum class LC_STATE {
|
||||||
LCS_NONE,
|
NONE,
|
||||||
LCS_FIRST,
|
FIRST,
|
||||||
LCS_SECOND,
|
SECOND,
|
||||||
LCS_THIRD
|
THIRD
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDMREmbeddedData
|
class CDMREmbeddedData
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021,2025 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
|
||||||
|
|
@ -157,7 +157,7 @@ bool CDMRGatewayNetwork::read(CDMRData& data)
|
||||||
if (slotNo == 2U && !m_slot2)
|
if (slotNo == 2U && !m_slot2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO::USER_USER : FLCO::GROUP;
|
||||||
|
|
||||||
data.setSeqNo(seqNo);
|
data.setSeqNo(seqNo);
|
||||||
data.setSlotNo(slotNo);
|
data.setSlotNo(slotNo);
|
||||||
|
|
@ -220,7 +220,7 @@ bool CDMRGatewayNetwork::write(const CDMRData& data)
|
||||||
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||||
|
|
||||||
FLCO flco = data.getFLCO();
|
FLCO flco = data.getFLCO();
|
||||||
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
buffer[15U] |= flco == FLCO::GROUP ? 0x00U : 0x40U;
|
||||||
|
|
||||||
unsigned int slotIndex = slotNo - 1U;
|
unsigned int slotIndex = slotNo - 1U;
|
||||||
|
|
||||||
|
|
@ -349,16 +349,16 @@ bool CDMRGatewayNetwork::writeConfig()
|
||||||
slots = '2';
|
slots = '2';
|
||||||
|
|
||||||
switch (m_hwType) {
|
switch (m_hwType) {
|
||||||
case HWT_MMDVM:
|
case HW_TYPE::MMDVM:
|
||||||
software = "MMDVM";
|
software = "MMDVM";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS:
|
case HW_TYPE::MMDVM_HS:
|
||||||
software = "MMDVM_MMDVM_HS";
|
software = "MMDVM_MMDVM_HS";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS_DUAL_HAT:
|
case HW_TYPE::MMDVM_HS_DUAL_HAT:
|
||||||
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
break;
|
break;
|
||||||
case HWT_NANO_HOTSPOT:
|
case HW_TYPE::NANO_HOTSPOT:
|
||||||
software = "MMDVM_Nano_hotSPOT";
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -369,37 +369,37 @@ bool CDMRGatewayNetwork::writeConfig()
|
||||||
slots = '4';
|
slots = '4';
|
||||||
|
|
||||||
switch (m_hwType) {
|
switch (m_hwType) {
|
||||||
case HWT_MMDVM:
|
case HW_TYPE::MMDVM:
|
||||||
software = "MMDVM_DMO";
|
software = "MMDVM_DMO";
|
||||||
break;
|
break;
|
||||||
case HWT_DVMEGA:
|
case HW_TYPE::DVMEGA:
|
||||||
software = "MMDVM_DVMega";
|
software = "MMDVM_DVMega";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_ZUMSPOT:
|
case HW_TYPE::MMDVM_ZUMSPOT:
|
||||||
software = "MMDVM_ZUMspot";
|
software = "MMDVM_ZUMspot";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS_HAT:
|
case HW_TYPE::MMDVM_HS_HAT:
|
||||||
software = "MMDVM_MMDVM_HS_Hat";
|
software = "MMDVM_MMDVM_HS_Hat";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS_DUAL_HAT:
|
case HW_TYPE::MMDVM_HS_DUAL_HAT:
|
||||||
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
break;
|
break;
|
||||||
case HWT_NANO_HOTSPOT:
|
case HW_TYPE::NANO_HOTSPOT:
|
||||||
software = "MMDVM_Nano_hotSPOT";
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
break;
|
break;
|
||||||
case HWT_NANO_DV:
|
case HW_TYPE::NANO_DV:
|
||||||
software = "MMDVM_Nano_DV";
|
software = "MMDVM_Nano_DV";
|
||||||
break;
|
break;
|
||||||
case HWT_D2RG_MMDVM_HS:
|
case HW_TYPE::D2RG_MMDVM_HS:
|
||||||
software = "MMDVM_D2RG_MMDVM_HS";
|
software = "MMDVM_D2RG_MMDVM_HS";
|
||||||
break;
|
break;
|
||||||
case HWT_MMDVM_HS:
|
case HW_TYPE::MMDVM_HS:
|
||||||
software = "MMDVM_MMDVM_HS";
|
software = "MMDVM_MMDVM_HS";
|
||||||
break;
|
break;
|
||||||
case HWT_OPENGD77_HS:
|
case HW_TYPE::OPENGD77_HS:
|
||||||
software = "MMDVM_OpenGD77_HS";
|
software = "MMDVM_OpenGD77_HS";
|
||||||
break;
|
break;
|
||||||
case HWT_SKYBRIDGE:
|
case HW_TYPE::SKYBRIDGE:
|
||||||
software = "MMDVM_SkyBridge";
|
software = "MMDVM_SkyBridge";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2019,2021,2022 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2019,2021,2022,2025 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
|
||||||
|
|
@ -37,7 +37,7 @@ m_dstId(dstId)
|
||||||
CDMRLC::CDMRLC(const unsigned char* bytes) :
|
CDMRLC::CDMRLC(const unsigned char* bytes) :
|
||||||
m_PF(false),
|
m_PF(false),
|
||||||
m_R(false),
|
m_R(false),
|
||||||
m_FLCO(FLCO_GROUP),
|
m_FLCO(FLCO::GROUP),
|
||||||
m_FID(0U),
|
m_FID(0U),
|
||||||
m_options(0U),
|
m_options(0U),
|
||||||
m_srcId(0U),
|
m_srcId(0U),
|
||||||
|
|
@ -61,7 +61,7 @@ m_dstId(0U)
|
||||||
CDMRLC::CDMRLC(const bool* bits) :
|
CDMRLC::CDMRLC(const bool* bits) :
|
||||||
m_PF(false),
|
m_PF(false),
|
||||||
m_R(false),
|
m_R(false),
|
||||||
m_FLCO(FLCO_GROUP),
|
m_FLCO(FLCO::GROUP),
|
||||||
m_FID(0U),
|
m_FID(0U),
|
||||||
m_options(0U),
|
m_options(0U),
|
||||||
m_srcId(0U),
|
m_srcId(0U),
|
||||||
|
|
@ -99,7 +99,7 @@ m_dstId(0U)
|
||||||
CDMRLC::CDMRLC() :
|
CDMRLC::CDMRLC() :
|
||||||
m_PF(false),
|
m_PF(false),
|
||||||
m_R(false),
|
m_R(false),
|
||||||
m_FLCO(FLCO_GROUP),
|
m_FLCO(FLCO::GROUP),
|
||||||
m_FID(0U),
|
m_FID(0U),
|
||||||
m_options(0U),
|
m_options(0U),
|
||||||
m_srcId(0U),
|
m_srcId(0U),
|
||||||
|
|
|
||||||
316
DMRSlot.cpp
316
DMRSlot.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021,2023 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015-2021,2023,2025 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
|
||||||
|
|
@ -43,7 +43,7 @@ CDisplay* CDMRSlot::m_display = NULL;
|
||||||
bool CDMRSlot::m_duplex = true;
|
bool CDMRSlot::m_duplex = true;
|
||||||
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
||||||
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
||||||
DMR_OVCM_TYPES CDMRSlot::m_ovcm = DMR_OVCM_OFF;
|
DMR_OVCM CDMRSlot::m_ovcm = DMR_OVCM::OFF;
|
||||||
bool CDMRSlot::m_protect = false;
|
bool CDMRSlot::m_protect = false;
|
||||||
|
|
||||||
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
||||||
|
|
@ -55,10 +55,10 @@ unsigned char* CDMRSlot::m_idle = NULL;
|
||||||
|
|
||||||
FLCO CDMRSlot::m_flco1;
|
FLCO CDMRSlot::m_flco1;
|
||||||
unsigned char CDMRSlot::m_id1 = 0U;
|
unsigned char CDMRSlot::m_id1 = 0U;
|
||||||
ACTIVITY_TYPE CDMRSlot::m_activity1 = ACTIVITY_NONE;
|
ACTIVITY_TYPE CDMRSlot::m_activity1 = ACTIVITY_TYPE::NONE;
|
||||||
FLCO CDMRSlot::m_flco2;
|
FLCO CDMRSlot::m_flco2;
|
||||||
unsigned char CDMRSlot::m_id2 = 0U;
|
unsigned char CDMRSlot::m_id2 = 0U;
|
||||||
ACTIVITY_TYPE CDMRSlot::m_activity2 = ACTIVITY_NONE;
|
ACTIVITY_TYPE CDMRSlot::m_activity2 = ACTIVITY_TYPE::NONE;
|
||||||
|
|
||||||
const unsigned char TALKER_ID_NONE = 0x00U;
|
const unsigned char TALKER_ID_NONE = 0x00U;
|
||||||
const unsigned char TALKER_ID_HEADER = 0x01U;
|
const unsigned char TALKER_ID_HEADER = 0x01U;
|
||||||
|
|
@ -75,8 +75,8 @@ const unsigned int NO_PREAMBLE_CSBK = 15U;
|
||||||
CDMRSlot::CDMRSlot(unsigned int slotNo, unsigned int timeout) :
|
CDMRSlot::CDMRSlot(unsigned int slotNo, unsigned int timeout) :
|
||||||
m_slotNo(slotNo),
|
m_slotNo(slotNo),
|
||||||
m_queue(5000U, "DMR Slot"),
|
m_queue(5000U, "DMR Slot"),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RPT_RF_STATE::LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RPT_NET_STATE::IDLE),
|
||||||
m_rfEmbeddedLC(),
|
m_rfEmbeddedLC(),
|
||||||
m_rfEmbeddedData(NULL),
|
m_rfEmbeddedData(NULL),
|
||||||
m_rfEmbeddedReadN(0U),
|
m_rfEmbeddedReadN(0U),
|
||||||
|
|
@ -143,15 +143,15 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if ((data[0U] == TAG_LOST) && (m_rfState == RPT_RF_STATE::AUDIO)) {
|
||||||
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
||||||
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
||||||
FLCO flco = m_rfLC->getFLCO();
|
FLCO flco = m_rfLC->getFLCO();
|
||||||
|
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("DMR Slot %u, RF voice transmission lost from %s to %s%s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("DMR Slot %u, RF voice transmission lost from %s to %s%s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
LogMessage("DMR Slot %u, RF voice transmission lost from %s to %s%s, %.1f seconds, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("DMR Slot %u, RF voice transmission lost from %s to %s%s, %.1f seconds, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
if (m_rfTimeout) {
|
if (m_rfTimeout) {
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -161,18 +161,18 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_DATA) {
|
if ((data[0U] == TAG_LOST) && (m_rfState == RPT_RF_STATE::DATA)) {
|
||||||
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
||||||
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
||||||
FLCO flco = m_rfLC->getFLCO();
|
FLCO flco = m_rfLC->getFLCO();
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, RF data transmission lost from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, RF data transmission lost from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str());
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST) {
|
if (data[0U] == TAG_LOST) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
slotType.setDataType(dataType);
|
slotType.setDataType(dataType);
|
||||||
|
|
||||||
if (dataType == DT_VOICE_LC_HEADER) {
|
if (dataType == DT_VOICE_LC_HEADER) {
|
||||||
if (m_rfState == RS_RF_AUDIO)
|
if (m_rfState == RPT_RF_STATE::AUDIO)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
CDMRFullLC fullLC;
|
CDMRFullLC fullLC;
|
||||||
|
|
@ -227,7 +227,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (lc->getPF()) {
|
if (lc->getPF()) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,20 +235,20 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO_GROUP, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO::GROUP, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
delete lc;
|
delete lc;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::TX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
lc->setOVCM(true);
|
lc->setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
lc->setOVCM(false);
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_rfLC = lc;
|
m_rfLC = lc;
|
||||||
|
|
@ -297,22 +297,22 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
writeNetworkRF(data, DT_VOICE_LC_HEADER);
|
writeNetworkRF(data, DT_VOICE_LC_HEADER);
|
||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, flco, ACTIVITY_TYPE::VOICE);
|
||||||
m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "R");
|
m_display->writeDMR(m_slotNo, src, flco == FLCO::GROUP, dst, "R");
|
||||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received RF voice header from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF voice header from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (dataType == DT_VOICE_PI_HEADER) {
|
} else if (dataType == DT_VOICE_PI_HEADER) {
|
||||||
if (m_rfState != RS_RF_AUDIO)
|
if (m_rfState != RPT_RF_STATE::AUDIO)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Regenerate the Slot Type
|
// Regenerate the Slot Type
|
||||||
|
|
@ -339,7 +339,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (dataType == DT_TERMINATOR_WITH_LC) {
|
} else if (dataType == DT_TERMINATOR_WITH_LC) {
|
||||||
if (m_rfState != RS_RF_AUDIO)
|
if (m_rfState != RPT_RF_STATE::AUDIO)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Regenerate the LC data
|
// Regenerate the LC data
|
||||||
|
|
@ -369,9 +369,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
FLCO flco = m_rfLC->getFLCO();
|
FLCO flco = m_rfLC->getFLCO();
|
||||||
|
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("DMR Slot %u, received RF end of voice transmission from %s to %s%s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("DMR Slot %u, received RF end of voice transmission from %s to %s%s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
LogMessage("DMR Slot %u, received RF end of voice transmission from %s to %s%s, %.1f seconds, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("DMR Slot %u, received RF end of voice transmission from %s to %s%s, %.1f seconds, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
||||||
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
||||||
|
|
||||||
|
|
@ -383,7 +383,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (dataType == DT_DATA_HEADER) {
|
} else if (dataType == DT_DATA_HEADER) {
|
||||||
if (m_rfState == RS_RF_DATA)
|
if (m_rfState == RPT_RF_STATE::DATA)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
CDMRDataHeader dataHeader;
|
CDMRDataHeader dataHeader;
|
||||||
|
|
@ -397,19 +397,19 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfFrames = dataHeader.getBlocks();
|
m_rfFrames = dataHeader.getBlocks();
|
||||||
|
|
||||||
m_rfLC = new CDMRLC(gi ? FLCO_GROUP : FLCO_USER_USER, srcId, dstId);
|
m_rfLC = new CDMRLC(gi ? FLCO::GROUP : FLCO::USER_USER, srcId, dstId);
|
||||||
|
|
||||||
// Regenerate the data header
|
// Regenerate the data header
|
||||||
dataHeader.get(data + 2U);
|
dataHeader.get(data + 2U);
|
||||||
|
|
@ -428,13 +428,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
writeNetworkRF(data, DT_DATA_HEADER);
|
writeNetworkRF(data, DT_DATA_HEADER);
|
||||||
|
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
setShortLC(m_slotNo, dstId, gi ? FLCO::GROUP : FLCO::USER_USER, ACTIVITY_TYPE::DATA);
|
||||||
m_display->writeDMR(m_slotNo, src, gi, dst, "R");
|
m_display->writeDMR(m_slotNo, src, gi, dst, "R");
|
||||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||||
}
|
}
|
||||||
|
|
@ -454,13 +454,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CSBKO csbko = csbk.getCSBKO();
|
CSBKO csbko = csbk.getCSBKO();
|
||||||
if (csbko == CSBKO_BSDWNACT)
|
if (csbko == CSBKO::BSDWNACT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// set the OVCM bit for the supported csbk
|
// set the OVCM bit for the supported csbk
|
||||||
if (m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::TX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
csbk.setOVCM(true);
|
csbk.setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
csbk.setOVCM(false);
|
csbk.setOVCM(false);
|
||||||
|
|
||||||
bool gi = csbk.getGI();
|
bool gi = csbk.getGI();
|
||||||
|
|
@ -470,13 +470,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (srcId != 0U || dstId != 0U) {
|
if (srcId != 0U || dstId != 0U) {
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -496,34 +496,34 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (m_duplex)
|
if (m_duplex)
|
||||||
writeQueueRF(data);
|
writeQueueRF(data);
|
||||||
|
|
||||||
writeNetworkRF(data, DT_CSBK, gi ? FLCO_GROUP : FLCO_USER_USER, srcId, dstId);
|
writeNetworkRF(data, DT_CSBK, gi ? FLCO::GROUP : FLCO::USER_USER, srcId, dstId);
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
||||||
switch (csbko) {
|
switch (csbko) {
|
||||||
case CSBKO_UUVREQ:
|
case CSBKO::UUVREQ:
|
||||||
LogMessage("DMR Slot %u, received RF Unit to Unit Voice Service Request CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Unit to Unit Voice Service Request CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_UUANSRSP:
|
case CSBKO::UUANSRSP:
|
||||||
LogMessage("DMR Slot %u, received RF Unit to Unit Voice Service Answer Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Unit to Unit Voice Service Answer Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_NACKRSP:
|
case CSBKO::NACKRSP:
|
||||||
LogMessage("DMR Slot %u, received RF Negative Acknowledgment Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Negative Acknowledgment Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_PRECCSBK:
|
case CSBKO::PRECCSBK:
|
||||||
LogMessage("DMR Slot %u, received RF %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_CALL_ALERT:
|
case CSBKO::CALL_ALERT:
|
||||||
LogMessage("DMR Slot %u, received RF Call Alert CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Call Alert CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_CALL_ALERT_ACK:
|
case CSBKO::CALL_ALERT_ACK:
|
||||||
LogMessage("DMR Slot %u, received RF Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_RADIO_CHECK:
|
case CSBKO::RADIO_CHECK:
|
||||||
LogMessage("DMR Slot %u, received RF Radio Check %s CSBK from %s to %s%s", m_slotNo, /* TBD */ 1 ? "Req" : "Ack", src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Radio Check %s CSBK from %s to %s%s", m_slotNo, /* TBD */ 1 ? "Req" : "Ack", src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_CALL_EMERGENCY:
|
case CSBKO::CALL_EMERGENCY:
|
||||||
LogMessage("DMR Slot %u, received RF Call Emergency CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Call Emergency CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -532,15 +532,15 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If data preamble, signal its existence
|
// If data preamble, signal its existence
|
||||||
if (m_netState == RS_NET_IDLE && csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
|
if ((m_netState == RPT_NET_STATE::IDLE) && (csbko == CSBKO::PRECCSBK) && csbk.getDataContent()) {
|
||||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
setShortLC(m_slotNo, dstId, gi ? FLCO::GROUP : FLCO::USER_USER, ACTIVITY_TYPE::DATA);
|
||||||
m_display->writeDMR(m_slotNo, src, gi, dst, "R");
|
m_display->writeDMR(m_slotNo, src, gi, dst, "R");
|
||||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (dataType == DT_RATE_12_DATA || dataType == DT_RATE_34_DATA || dataType == DT_RATE_1_DATA) {
|
} else if ((dataType == DT_RATE_12_DATA) || (dataType == DT_RATE_34_DATA) || (dataType == DT_RATE_1_DATA)) {
|
||||||
if (m_rfState != RS_RF_DATA || m_rfFrames == 0U)
|
if ((m_rfState != RPT_RF_STATE::DATA) || (m_rfFrames == 0U))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char title[80U];
|
char title[80U];
|
||||||
|
|
@ -593,7 +593,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (audioSync) {
|
} else if (audioSync) {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
m_lastrfN = 0;
|
m_lastrfN = 0;
|
||||||
// Convert the Audio Sync to be from the BS or MS as needed
|
// Convert the Audio Sync to be from the BS or MS as needed
|
||||||
CSync::addDMRAudioSync(data + 2U, m_duplex);
|
CSync::addDMRAudioSync(data + 2U, m_duplex);
|
||||||
|
|
@ -630,13 +630,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (m_rfState == RS_RF_LISTENING) {
|
} else if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
m_rfEmbeddedLC.reset();
|
m_rfEmbeddedLC.reset();
|
||||||
m_rfState = RS_RF_LATE_ENTRY;
|
m_rfState = RPT_RF_STATE::LATE_ENTRY;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
m_rfN = data[1U] & 0x0FU;
|
m_rfN = data[1U] & 0x0FU;
|
||||||
if (m_rfN > 5U)
|
if (m_rfN > 5U)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -673,13 +673,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
char text[80U];
|
char text[80U];
|
||||||
switch (flco) {
|
switch (flco) {
|
||||||
case FLCO_GROUP:
|
case FLCO::GROUP:
|
||||||
case FLCO_USER_USER:
|
case FLCO::USER_USER:
|
||||||
// ::sprintf(text, "DMR Slot %u, Embedded LC", m_slotNo);
|
// ::sprintf(text, "DMR Slot %u, Embedded LC", m_slotNo);
|
||||||
// CUtils::dump(1U, text, data, 9U);
|
// CUtils::dump(1U, text, data, 9U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_GPS_INFO:
|
case FLCO::GINFO:
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
||||||
CUtils::dump(1U, text, data, 9U);
|
CUtils::dump(1U, text, data, 9U);
|
||||||
|
|
@ -689,7 +689,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_network->writeRadioPosition(m_rfLC->getSrcId(), data);
|
m_network->writeRadioPosition(m_rfLC->getSrcId(), data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_HEADER:
|
case FLCO::TALKER_ALIAS_HEADER:
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 0U, data);
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 0U, data);
|
||||||
|
|
||||||
|
|
@ -708,7 +708,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_BLOCK1:
|
case FLCO::TALKER_ALIAS_BLOCK1:
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 1U, data);
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 1U, data);
|
||||||
|
|
||||||
|
|
@ -727,7 +727,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_BLOCK2:
|
case FLCO::TALKER_ALIAS_BLOCK2:
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 2U, data);
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 2U, data);
|
||||||
|
|
||||||
|
|
@ -746,7 +746,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_BLOCK3:
|
case FLCO::TALKER_ALIAS_BLOCK3:
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 3U, data);
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 3U, data);
|
||||||
|
|
||||||
|
|
@ -806,7 +806,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (m_rfState == RS_RF_LATE_ENTRY) {
|
} else if (m_rfState == RPT_RF_STATE::LATE_ENTRY) {
|
||||||
CDMREMB emb;
|
CDMREMB emb;
|
||||||
emb.putData(data + 2U);
|
emb.putData(data + 2U);
|
||||||
|
|
||||||
|
|
@ -826,7 +826,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (lc->getPF()) {
|
if (lc->getPF()) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -834,20 +834,20 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO_GROUP, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO::GROUP, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
delete lc;
|
delete lc;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::TX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
lc->setOVCM(true);
|
lc->setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
lc->setOVCM(false);
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_rfLC = lc;
|
m_rfLC = lc;
|
||||||
|
|
@ -930,19 +930,19 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
writeNetworkRF(data, DT_VOICE, errors);
|
writeNetworkRF(data, DT_VOICE, errors);
|
||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, flco, ACTIVITY_TYPE::VOICE);
|
||||||
m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "R");
|
m_display->writeDMR(m_slotNo, src, flco == FLCO::GROUP, dst, "R");
|
||||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||||
m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F);
|
m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received RF late entry from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF late entry from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -969,15 +969,15 @@ unsigned int CDMRSlot::readModem(unsigned char* data)
|
||||||
|
|
||||||
void CDMRSlot::writeEndRF(bool writeEnd)
|
void CDMRSlot::writeEndRF(bool writeEnd)
|
||||||
{
|
{
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
setShortLC(m_slotNo, 0U);
|
setShortLC(m_slotNo, 0U);
|
||||||
m_display->clearDMR(m_slotNo);
|
m_display->clearDMR(m_slotNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeEnd) {
|
if (writeEnd) {
|
||||||
if (m_netState == RS_NET_IDLE && m_duplex && !m_rfTimeout) {
|
if ((m_netState == RPT_NET_STATE::IDLE) && m_duplex && !m_rfTimeout) {
|
||||||
// Create a dummy start end frame
|
// Create a dummy start end frame
|
||||||
unsigned char data[DMR_FRAME_LENGTH_BYTES + 2U];
|
unsigned char data[DMR_FRAME_LENGTH_BYTES + 2U];
|
||||||
|
|
||||||
|
|
@ -1015,7 +1015,7 @@ void CDMRSlot::writeEndRF(bool writeEnd)
|
||||||
|
|
||||||
void CDMRSlot::writeEndNet(bool writeEnd)
|
void CDMRSlot::writeEndNet(bool writeEnd)
|
||||||
{
|
{
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
setShortLC(m_slotNo, 0U);
|
setShortLC(m_slotNo, 0U);
|
||||||
|
|
||||||
|
|
@ -1075,7 +1075,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
if ((m_rfState != RPT_RF_STATE::LISTENING) && (m_netState == RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
@ -1086,7 +1086,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
dmrData.getData(data + 2U);
|
dmrData.getData(data + 2U);
|
||||||
|
|
||||||
if (dataType == DT_VOICE_LC_HEADER) {
|
if (dataType == DT_VOICE_LC_HEADER) {
|
||||||
if (m_netState == RS_NET_AUDIO)
|
if (m_netState == RPT_NET_STATE::AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CDMRFullLC fullLC;
|
CDMRFullLC fullLC;
|
||||||
|
|
@ -1102,12 +1102,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
if (dstId != dmrData.getDstId() || srcId != dmrData.getSrcId() || flco != dmrData.getFLCO())
|
if (dstId != dmrData.getDstId() || srcId != dmrData.getSrcId() || flco != dmrData.getFLCO())
|
||||||
LogWarning("DMR Slot %u, DMRD header doesn't match the DMR RF header: %u->%s%u %u->%s%u", m_slotNo,
|
LogWarning("DMR Slot %u, DMRD header doesn't match the DMR RF header: %u->%s%u %u->%s%u", m_slotNo,
|
||||||
dmrData.getSrcId(), dmrData.getFLCO() == FLCO_GROUP ? "TG" : "", dmrData.getDstId(),
|
dmrData.getSrcId(), dmrData.getFLCO() == FLCO::GROUP ? "TG" : "", dmrData.getDstId(),
|
||||||
srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
srcId, flco == FLCO::GROUP ? "TG" : "", dstId);
|
||||||
|
|
||||||
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::RX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
lc->setOVCM(true);
|
lc->setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
lc->setOVCM(false);
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
@ -1162,31 +1162,31 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
writeQueueNet(data);
|
writeQueueNet(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
|
|
||||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, flco, ACTIVITY_TYPE::VOICE);
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
class CUserDBentry cn;
|
class CUserDBentry cn;
|
||||||
m_lookup->findWithName(srcId, &cn);
|
m_lookup->findWithName(srcId, &cn);
|
||||||
m_display->writeDMR(m_slotNo, cn, flco == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, cn, flco == FLCO::GROUP, dst, "N");
|
||||||
|
|
||||||
#if defined(DUMP_DMR)
|
#if defined(DUMP_DMR)
|
||||||
openFile();
|
openFile();
|
||||||
writeFile(data);
|
writeFile(data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received network voice header from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network voice header from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str());
|
||||||
} else if (dataType == DT_VOICE_PI_HEADER) {
|
} else if (dataType == DT_VOICE_PI_HEADER) {
|
||||||
if (m_netState != RS_NET_AUDIO) {
|
if (m_netState != RPT_NET_STATE::AUDIO) {
|
||||||
CDMRLC* lc = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
|
CDMRLC* lc = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
|
||||||
|
|
||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
unsigned int srcId = lc->getSrcId();
|
unsigned int srcId = lc->getSrcId();
|
||||||
|
|
||||||
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::RX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
lc->setOVCM(true);
|
lc->setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
lc->setOVCM(false);
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
@ -1236,17 +1236,17 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
m_netBits = 1U;
|
m_netBits = 1U;
|
||||||
m_netErrs = 0U;
|
m_netErrs = 0U;
|
||||||
|
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
|
|
||||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_TYPE::VOICE);
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
class CUserDBentry cn;
|
class CUserDBentry cn;
|
||||||
m_lookup->findWithName(srcId, &cn);
|
m_lookup->findWithName(srcId, &cn);
|
||||||
|
|
||||||
m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO::GROUP, dst, "N");
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO::GROUP ? "TG " : "", dst.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerate the Slot Type
|
// Regenerate the Slot Type
|
||||||
|
|
@ -1274,7 +1274,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
writeFile(data);
|
writeFile(data);
|
||||||
#endif
|
#endif
|
||||||
} else if (dataType == DT_TERMINATOR_WITH_LC) {
|
} else if (dataType == DT_TERMINATOR_WITH_LC) {
|
||||||
if (m_netState != RS_NET_AUDIO)
|
if (m_netState != RPT_NET_STATE::AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Regenerate the LC data
|
// Regenerate the LC data
|
||||||
|
|
@ -1313,11 +1313,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
// We've received the voice header and terminator haven't we?
|
// We've received the voice header and terminator haven't we?
|
||||||
m_netFrames += 2U;
|
m_netFrames += 2U;
|
||||||
LogMessage("DMR Slot %u, received network end of voice transmission from %s to %s%s, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
LogMessage("DMR Slot %u, received network end of voice transmission from %s to %s%s, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO::GROUP ? "TG " : "", dst.c_str(), float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
} else if (dataType == DT_DATA_HEADER) {
|
} else if (dataType == DT_DATA_HEADER) {
|
||||||
if (m_netState == RS_NET_DATA)
|
if (m_netState == RPT_NET_STATE::DATA)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CDMRDataHeader dataHeader;
|
CDMRDataHeader dataHeader;
|
||||||
|
|
@ -1354,9 +1354,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
writeQueueNet(data);
|
writeQueueNet(data);
|
||||||
|
|
||||||
m_netState = RS_NET_DATA;
|
m_netState = RPT_NET_STATE::DATA;
|
||||||
|
|
||||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
setShortLC(m_slotNo, dstId, gi ? FLCO::GROUP : FLCO::USER_USER, ACTIVITY_TYPE::DATA);
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
@ -1370,15 +1370,15 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
}
|
}
|
||||||
} else if (dataType == DT_VOICE_SYNC) {
|
} else if (dataType == DT_VOICE_SYNC) {
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
CDMRLC* lc = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
|
CDMRLC* lc = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
|
||||||
|
|
||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
unsigned int srcId = lc->getSrcId();
|
unsigned int srcId = lc->getSrcId();
|
||||||
|
|
||||||
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::RX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
lc->setOVCM(true);
|
lc->setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
lc->setOVCM(false);
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
@ -1437,21 +1437,21 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
m_netEmbeddedWriteN = 1U;
|
m_netEmbeddedWriteN = 1U;
|
||||||
m_netTalkerId = TALKER_ID_NONE;
|
m_netTalkerId = TALKER_ID_NONE;
|
||||||
|
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
|
|
||||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_TYPE::VOICE);
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
class CUserDBentry cn;
|
class CUserDBentry cn;
|
||||||
m_lookup->findWithName(srcId, &cn);
|
m_lookup->findWithName(srcId, &cn);
|
||||||
|
|
||||||
m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO::GROUP, dst, "N");
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO::GROUP ? "TG " : "", dst.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
unsigned char fid = m_netLC->getFID();
|
unsigned char fid = m_netLC->getFID();
|
||||||
if (fid == FID_ETSI || fid == FID_DMRA)
|
if (fid == FID_ETSI || fid == FID_DMRA)
|
||||||
m_netErrs += m_fec.regenerateDMR(data + 2U);
|
m_netErrs += m_fec.regenerateDMR(data + 2U);
|
||||||
|
|
@ -1494,7 +1494,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (dataType == DT_VOICE) {
|
} else if (dataType == DT_VOICE) {
|
||||||
if (m_netState != RS_NET_AUDIO)
|
if (m_netState != RPT_NET_STATE::AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char fid = m_netLC->getFID();
|
unsigned char fid = m_netLC->getFID();
|
||||||
|
|
@ -1517,19 +1517,19 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
char text[80U];
|
char text[80U];
|
||||||
switch (flco) {
|
switch (flco) {
|
||||||
case FLCO_GROUP:
|
case FLCO::GROUP:
|
||||||
case FLCO_USER_USER:
|
case FLCO::USER_USER:
|
||||||
// ::sprintf(text, "DMR Slot %u, Embedded LC", m_slotNo);
|
// ::sprintf(text, "DMR Slot %u, Embedded LC", m_slotNo);
|
||||||
// CUtils::dump(1U, text, data, 9U);
|
// CUtils::dump(1U, text, data, 9U);
|
||||||
break;
|
break;
|
||||||
case FLCO_GPS_INFO:
|
case FLCO::GINFO:
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
||||||
CUtils::dump(1U, text, data, 9U);
|
CUtils::dump(1U, text, data, 9U);
|
||||||
logGPSPosition(data);
|
logGPSPosition(data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLCO_TALKER_ALIAS_HEADER:
|
case FLCO::TALKER_ALIAS_HEADER:
|
||||||
if (!(m_netTalkerId & TALKER_ID_HEADER)) {
|
if (!(m_netTalkerId & TALKER_ID_HEADER)) {
|
||||||
if (!m_netTalkerId)
|
if (!m_netTalkerId)
|
||||||
m_netTalkerAlias.reset();
|
m_netTalkerAlias.reset();
|
||||||
|
|
@ -1544,7 +1544,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
m_netTalkerId |= TALKER_ID_HEADER;
|
m_netTalkerId |= TALKER_ID_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLCO_TALKER_ALIAS_BLOCK1:
|
case FLCO::TALKER_ALIAS_BLOCK1:
|
||||||
if (!(m_netTalkerId & TALKER_ID_BLOCK1)) {
|
if (!(m_netTalkerId & TALKER_ID_BLOCK1)) {
|
||||||
if (!m_netTalkerId)
|
if (!m_netTalkerId)
|
||||||
m_netTalkerAlias.reset();
|
m_netTalkerAlias.reset();
|
||||||
|
|
@ -1559,7 +1559,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
m_netTalkerId |= TALKER_ID_BLOCK1;
|
m_netTalkerId |= TALKER_ID_BLOCK1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLCO_TALKER_ALIAS_BLOCK2:
|
case FLCO::TALKER_ALIAS_BLOCK2:
|
||||||
if (!(m_netTalkerId & TALKER_ID_BLOCK2)) {
|
if (!(m_netTalkerId & TALKER_ID_BLOCK2)) {
|
||||||
if (!m_netTalkerId)
|
if (!m_netTalkerId)
|
||||||
m_netTalkerAlias.reset();
|
m_netTalkerAlias.reset();
|
||||||
|
|
@ -1574,7 +1574,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
m_netTalkerId |= TALKER_ID_BLOCK2;
|
m_netTalkerId |= TALKER_ID_BLOCK2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLCO_TALKER_ALIAS_BLOCK3:
|
case FLCO::TALKER_ALIAS_BLOCK3:
|
||||||
if (!(m_netTalkerId & TALKER_ID_BLOCK3)) {
|
if (!(m_netTalkerId & TALKER_ID_BLOCK3)) {
|
||||||
if (!m_netTalkerId)
|
if (!m_netTalkerId)
|
||||||
m_netTalkerAlias.reset();
|
m_netTalkerAlias.reset();
|
||||||
|
|
@ -1648,13 +1648,13 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
}
|
}
|
||||||
|
|
||||||
CSBKO csbko = csbk.getCSBKO();
|
CSBKO csbko = csbk.getCSBKO();
|
||||||
if (csbko == CSBKO_BSDWNACT)
|
if (csbko == CSBKO::BSDWNACT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// set the OVCM bit for the supported csbk
|
// set the OVCM bit for the supported csbk
|
||||||
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
if ((m_ovcm == DMR_OVCM::RX_ON) || (m_ovcm == DMR_OVCM::ON))
|
||||||
csbk.setOVCM(true);
|
csbk.setOVCM(true);
|
||||||
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
else if (m_ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
csbk.setOVCM(false);
|
csbk.setOVCM(false);
|
||||||
|
|
||||||
bool gi = csbk.getGI();
|
bool gi = csbk.getGI();
|
||||||
|
|
@ -1676,7 +1676,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
if (csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
|
if ((csbko == CSBKO::PRECCSBK) && csbk.getDataContent()) {
|
||||||
unsigned int cbf = NO_PREAMBLE_CSBK + csbk.getCBF() - 1U;
|
unsigned int cbf = NO_PREAMBLE_CSBK + csbk.getCBF() - 1U;
|
||||||
for (unsigned int i = 0U; i < NO_PREAMBLE_CSBK; i++, cbf--) {
|
for (unsigned int i = 0U; i < NO_PREAMBLE_CSBK; i++, cbf--) {
|
||||||
// Change blocks to follow
|
// Change blocks to follow
|
||||||
|
|
@ -1709,25 +1709,25 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
||||||
switch (csbko) {
|
switch (csbko) {
|
||||||
case CSBKO_UUVREQ:
|
case CSBKO::UUVREQ:
|
||||||
LogMessage("DMR Slot %u, received network Unit to Unit Voice Service Request CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Unit to Unit Voice Service Request CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_UUANSRSP:
|
case CSBKO::UUANSRSP:
|
||||||
LogMessage("DMR Slot %u, received network Unit to Unit Voice Service Answer Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Unit to Unit Voice Service Answer Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_NACKRSP:
|
case CSBKO::NACKRSP:
|
||||||
LogMessage("DMR Slot %u, received network Negative Acknowledgment Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Negative Acknowledgment Response CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_PRECCSBK:
|
case CSBKO::PRECCSBK:
|
||||||
LogMessage("DMR Slot %u, received network %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_CALL_ALERT:
|
case CSBKO::CALL_ALERT:
|
||||||
LogMessage("DMR Slot %u, received network Call Alert CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Call Alert CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_CALL_ALERT_ACK:
|
case CSBKO::CALL_ALERT_ACK:
|
||||||
LogMessage("DMR Slot %u, received network Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
case CSBKO_RADIO_CHECK:
|
case CSBKO::RADIO_CHECK:
|
||||||
LogMessage("DMR Slot %u, received network Radio Check %s CSBK from %s to %s%s", m_slotNo, /* TBD */ 1 ? "Req" : "Ack", src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Radio Check %s CSBK from %s to %s%s", m_slotNo, /* TBD */ 1 ? "Req" : "Ack", src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -1736,12 +1736,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If data preamble, signal its existence
|
// If data preamble, signal its existence
|
||||||
if (csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
|
if ((csbko == CSBKO::PRECCSBK) && csbk.getDataContent()) {
|
||||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
setShortLC(m_slotNo, dstId, gi ? FLCO::GROUP : FLCO::USER_USER, ACTIVITY_TYPE::DATA);
|
||||||
m_display->writeDMR(m_slotNo, src, gi, dst, "N");
|
m_display->writeDMR(m_slotNo, src, gi, dst, "N");
|
||||||
}
|
}
|
||||||
} else if (dataType == DT_RATE_12_DATA || dataType == DT_RATE_34_DATA || dataType == DT_RATE_1_DATA) {
|
} else if ((dataType == DT_RATE_12_DATA) || (dataType == DT_RATE_34_DATA) || (dataType == DT_RATE_1_DATA)) {
|
||||||
if (m_netState != RS_NET_DATA || m_netFrames == 0U) {
|
if ((m_netState != RPT_NET_STATE::DATA) || (m_netFrames == 0U)) {
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1870,11 +1870,11 @@ void CDMRSlot::clock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) {
|
if ((m_netState == RPT_NET_STATE::AUDIO) || (m_netState == RPT_NET_STATE::DATA)) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
// We've received the voice header haven't we?
|
// We've received the voice header haven't we?
|
||||||
m_netFrames += 1U;
|
m_netFrames += 1U;
|
||||||
LogMessage("DMR Slot %u, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
LogMessage("DMR Slot %u, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
|
|
@ -1892,7 +1892,7 @@ void CDMRSlot::clock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
m_packetTimer.clock(ms);
|
m_packetTimer.clock(ms);
|
||||||
|
|
||||||
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
||||||
|
|
@ -1912,7 +1912,7 @@ void CDMRSlot::writeQueueRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char len = DMR_FRAME_LENGTH_BYTES + 2U;
|
unsigned char len = DMR_FRAME_LENGTH_BYTES + 2U;
|
||||||
|
|
@ -1931,7 +1931,7 @@ void CDMRSlot::writeNetworkRF(const unsigned char* data, unsigned char dataType,
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_network == NULL)
|
if (m_network == NULL)
|
||||||
|
|
@ -1979,7 +1979,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
|
||||||
m_queue.addData(data, len);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect)
|
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM ovcm, bool protect)
|
||||||
{
|
{
|
||||||
assert(modem != NULL);
|
assert(modem != NULL);
|
||||||
assert(display != NULL);
|
assert(display != NULL);
|
||||||
|
|
@ -2061,41 +2061,41 @@ void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, ACTIV
|
||||||
|
|
||||||
if (m_id1 != 0U) {
|
if (m_id1 != 0U) {
|
||||||
lc[2U] = m_id1;
|
lc[2U] = m_id1;
|
||||||
if (m_activity1 == ACTIVITY_VOICE && m_flco1 == FLCO_GROUP)
|
if ((m_activity1 == ACTIVITY_TYPE::VOICE) && (m_flco1 == FLCO::GROUP))
|
||||||
lc[1U] |= 0x08U;
|
lc[1U] |= 0x08U;
|
||||||
else if (m_activity1 == ACTIVITY_VOICE && m_flco1 == FLCO_USER_USER)
|
else if ((m_activity1 == ACTIVITY_TYPE::VOICE) && (m_flco1 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0x09U;
|
lc[1U] |= 0x09U;
|
||||||
else if (m_activity1 == ACTIVITY_DATA && m_flco1 == FLCO_GROUP)
|
else if ((m_activity1 == ACTIVITY_TYPE::DATA) && (m_flco1 == FLCO::GROUP))
|
||||||
lc[1U] |= 0x0BU;
|
lc[1U] |= 0x0BU;
|
||||||
else if (m_activity1 == ACTIVITY_DATA && m_flco1 == FLCO_USER_USER)
|
else if ((m_activity1 == ACTIVITY_TYPE::DATA) && (m_flco1 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0x0AU;
|
lc[1U] |= 0x0AU;
|
||||||
else if (m_activity1 == ACTIVITY_CSBK && m_flco1 == FLCO_GROUP)
|
else if ((m_activity1 == ACTIVITY_TYPE::CSBK) && (m_flco1 == FLCO::GROUP))
|
||||||
lc[1U] |= 0x02U;
|
lc[1U] |= 0x02U;
|
||||||
else if (m_activity1 == ACTIVITY_CSBK && m_flco1 == FLCO_USER_USER)
|
else if ((m_activity1 == ACTIVITY_TYPE::CSBK) && (m_flco1 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0x03U;
|
lc[1U] |= 0x03U;
|
||||||
else if (m_activity1 == ACTIVITY_EMERG && m_flco1 == FLCO_GROUP)
|
else if ((m_activity1 == ACTIVITY_TYPE::EMERG) && (m_flco1 == FLCO::GROUP))
|
||||||
lc[1U] |= 0x0CU;
|
lc[1U] |= 0x0CU;
|
||||||
else if (m_activity1 == ACTIVITY_EMERG && m_flco1 == FLCO_USER_USER)
|
else if ((m_activity1 == ACTIVITY_TYPE::EMERG) && (m_flco1 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0x0DU;
|
lc[1U] |= 0x0DU;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_id2 != 0U) {
|
if (m_id2 != 0U) {
|
||||||
lc[3U] = m_id2;
|
lc[3U] = m_id2;
|
||||||
if (m_activity2 == ACTIVITY_VOICE && m_flco2 == FLCO_GROUP)
|
if ((m_activity2 == ACTIVITY_TYPE::VOICE) && (m_flco2 == FLCO::GROUP))
|
||||||
lc[1U] |= 0x80U;
|
lc[1U] |= 0x80U;
|
||||||
else if (m_activity2 == ACTIVITY_VOICE && m_flco2 == FLCO_USER_USER)
|
else if ((m_activity2 == ACTIVITY_TYPE::VOICE) && (m_flco2 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0x90U;
|
lc[1U] |= 0x90U;
|
||||||
else if (m_activity2 == ACTIVITY_DATA && m_flco2 == FLCO_GROUP)
|
else if ((m_activity2 == ACTIVITY_TYPE::DATA) && (m_flco2 == FLCO::GROUP))
|
||||||
lc[1U] |= 0xB0U;
|
lc[1U] |= 0xB0U;
|
||||||
else if (m_activity2 == ACTIVITY_DATA && m_flco2 == FLCO_USER_USER)
|
else if ((m_activity2 == ACTIVITY_TYPE::DATA) && (m_flco2 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0xA0U;
|
lc[1U] |= 0xA0U;
|
||||||
else if (m_activity2 == ACTIVITY_CSBK && m_flco2 == FLCO_GROUP)
|
else if ((m_activity2 == ACTIVITY_TYPE::CSBK) && (m_flco2 == FLCO::GROUP))
|
||||||
lc[1U] |= 0x20U;
|
lc[1U] |= 0x20U;
|
||||||
else if (m_activity2 == ACTIVITY_CSBK && m_flco2 == FLCO_USER_USER)
|
else if ((m_activity2 == ACTIVITY_TYPE::CSBK) && (m_flco2 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0x30U;
|
lc[1U] |= 0x30U;
|
||||||
else if (m_activity2 == ACTIVITY_EMERG && m_flco2 == FLCO_GROUP)
|
else if ((m_activity2 == ACTIVITY_TYPE::EMERG) && (m_flco2 == FLCO::GROUP))
|
||||||
lc[1U] |= 0xC0U;
|
lc[1U] |= 0xC0U;
|
||||||
else if (m_activity2 == ACTIVITY_EMERG && m_flco2 == FLCO_USER_USER)
|
else if ((m_activity2 == ACTIVITY_TYPE::EMERG) && (m_flco2 == FLCO::USER_USER))
|
||||||
lc[1U] |= 0xD0U;
|
lc[1U] |= 0xD0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2229,7 +2229,7 @@ void CDMRSlot::insertSilence(unsigned int count)
|
||||||
|
|
||||||
bool CDMRSlot::isBusy() const
|
bool CDMRSlot::isBusy() const
|
||||||
{
|
{
|
||||||
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
|
return (m_rfState != RPT_RF_STATE::LISTENING) || (m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRSlot::enable(bool enabled)
|
void CDMRSlot::enable(bool enabled)
|
||||||
|
|
@ -2238,7 +2238,7 @@ void CDMRSlot::enable(bool enabled)
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
|
|
||||||
// Reset the RF section
|
// Reset the RF section
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
m_rfTimeout = false;
|
m_rfTimeout = false;
|
||||||
|
|
@ -2254,7 +2254,7 @@ void CDMRSlot::enable(bool enabled)
|
||||||
m_rfLC = NULL;
|
m_rfLC = NULL;
|
||||||
|
|
||||||
// Reset the networking section
|
// Reset the networking section
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_lastFrameValid = false;
|
m_lastFrameValid = false;
|
||||||
|
|
||||||
|
|
|
||||||
20
DMRSlot.h
20
DMRSlot.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021,2023 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021,2023,2025 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
|
||||||
|
|
@ -37,12 +37,12 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
enum ACTIVITY_TYPE {
|
enum class ACTIVITY_TYPE {
|
||||||
ACTIVITY_NONE,
|
NONE,
|
||||||
ACTIVITY_VOICE,
|
VOICE,
|
||||||
ACTIVITY_DATA,
|
DATA,
|
||||||
ACTIVITY_CSBK,
|
CSBK,
|
||||||
ACTIVITY_EMERG
|
EMERG
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDMRSlot {
|
class CDMRSlot {
|
||||||
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
void enable(bool enabled);
|
void enable(bool enabled);
|
||||||
|
|
||||||
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect);
|
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM ovcm, bool protect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_slotNo;
|
unsigned int m_slotNo;
|
||||||
|
|
@ -124,7 +124,7 @@ private:
|
||||||
static bool m_duplex;
|
static bool m_duplex;
|
||||||
static CDMRLookup* m_lookup;
|
static CDMRLookup* m_lookup;
|
||||||
static unsigned int m_hangCount;
|
static unsigned int m_hangCount;
|
||||||
static DMR_OVCM_TYPES m_ovcm;
|
static DMR_OVCM m_ovcm;
|
||||||
static bool m_protect;
|
static bool m_protect;
|
||||||
|
|
||||||
static CRSSIInterpolator* m_rssiMapper;
|
static CRSSIInterpolator* m_rssiMapper;
|
||||||
|
|
@ -158,7 +158,7 @@ private:
|
||||||
bool insertSilence(const unsigned char* data, unsigned char seqNo);
|
bool insertSilence(const unsigned char* data, unsigned char seqNo);
|
||||||
void insertSilence(unsigned int count);
|
void insertSilence(unsigned int count);
|
||||||
|
|
||||||
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, ACTIVITY_TYPE type = ACTIVITY_NONE);
|
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO::GROUP, ACTIVITY_TYPE type = ACTIVITY_TYPE::NONE);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
148
DStarControl.cpp
148
DStarControl.cpp
|
|
@ -37,7 +37,7 @@ bool CallsignCompare(const std::string& arg, const unsigned char* my)
|
||||||
|
|
||||||
// #define DUMP_DSTAR
|
// #define DUMP_DSTAR
|
||||||
|
|
||||||
CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, DSTAR_ACK_MESSAGE ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper) :
|
CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, DSTAR_ACK ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper) :
|
||||||
m_callsign(NULL),
|
m_callsign(NULL),
|
||||||
m_gateway(NULL),
|
m_gateway(NULL),
|
||||||
m_selfOnly(selfOnly),
|
m_selfOnly(selfOnly),
|
||||||
|
|
@ -53,8 +53,8 @@ m_duplex(duplex),
|
||||||
m_queue(5000U, "D-Star Control"),
|
m_queue(5000U, "D-Star Control"),
|
||||||
m_rfHeader(),
|
m_rfHeader(),
|
||||||
m_netHeader(),
|
m_netHeader(),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RPT_RF_STATE::LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RPT_NET_STATE::IDLE),
|
||||||
m_net(false),
|
m_net(false),
|
||||||
m_rfSlowData(),
|
m_rfSlowData(),
|
||||||
m_netSlowData(),
|
m_netSlowData(),
|
||||||
|
|
@ -129,7 +129,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && ((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA))) {
|
if (type == TAG_LOST && ((m_rfState == RPT_RF_STATE::AUDIO) || (m_rfState == RPT_RF_STATE::DATA))) {
|
||||||
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
||||||
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
|
|
@ -145,10 +145,10 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_INVALID) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::INVALID)) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
if (m_errorReply)
|
if (m_errorReply)
|
||||||
m_errTimer.start();
|
m_errTimer.start();
|
||||||
|
|
||||||
|
|
@ -160,7 +160,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST) {
|
if (type == TAG_LOST) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
// Is this a transmission destined for a repeater?
|
// Is this a transmission destined for a repeater?
|
||||||
if (!header.isRepeater()) {
|
if (!header.isRepeater()) {
|
||||||
LogMessage("D-Star, non repeater RF header received from %8.8s", my1);
|
LogMessage("D-Star, non repeater RF header received from %8.8s", my1);
|
||||||
m_rfState = RS_RF_INVALID;
|
m_rfState = RPT_RF_STATE::INVALID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,19 +230,19 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
// Is it for us?
|
// Is it for us?
|
||||||
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) {
|
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) {
|
||||||
LogMessage("D-Star, received RF header for wrong repeater (%8.8s) from %8.8s", callsign, my1);
|
LogMessage("D-Star, received RF header for wrong repeater (%8.8s) from %8.8s", callsign, my1);
|
||||||
m_rfState = RS_RF_INVALID;
|
m_rfState = RPT_RF_STATE::INVALID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0 && !(std::find_if(m_whiteList.begin(), m_whiteList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_whiteList.end())) {
|
if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0 && !(std::find_if(m_whiteList.begin(), m_whiteList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_whiteList.end())) {
|
||||||
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) {
|
if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) {
|
||||||
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,21 +297,21 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
writeNetworkHeaderRF(data);
|
writeNetworkHeaderRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
|
||||||
m_display->writeDStarRSSI(m_rssi);
|
m_display->writeDStarRSSI(m_rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage("D-Star, received RF header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
LogMessage("D-Star, received RF header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
||||||
} else if (type == TAG_EOT) {
|
} else if (type == TAG_EOT) {
|
||||||
if (m_rfState == RS_RF_REJECTED) {
|
if (m_rfState == RPT_RF_STATE::REJECTED) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
} else if (m_rfState == RS_RF_INVALID) {
|
} else if (m_rfState == RPT_RF_STATE::INVALID) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
if (m_errorReply)
|
if (m_errorReply)
|
||||||
m_errTimer.start();
|
m_errTimer.start();
|
||||||
|
|
||||||
|
|
@ -320,7 +320,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if ((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA)) {
|
} else if ((m_rfState == RPT_RF_STATE::AUDIO) || (m_rfState == RPT_RF_STATE::DATA)) {
|
||||||
if (m_net)
|
if (m_net)
|
||||||
writeNetworkDataRF(DSTAR_END_PATTERN_BYTES, 0U, true);
|
writeNetworkDataRF(DSTAR_END_PATTERN_BYTES, 0U, true);
|
||||||
|
|
||||||
|
|
@ -344,24 +344,24 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (type == TAG_DATA) {
|
} else if (type == TAG_DATA) {
|
||||||
if (m_rfState == RS_RF_REJECTED)
|
if (m_rfState == RPT_RF_STATE::REJECTED)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_rfState == RS_RF_INVALID)
|
if (m_rfState == RPT_RF_STATE::INVALID)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_rfSlowData.start();
|
m_rfSlowData.start();
|
||||||
m_rfN = 0U;
|
m_rfN = 0U;
|
||||||
m_rfState = RS_RF_LATE_ENTRY;
|
m_rfState = RPT_RF_STATE::LATE_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA)) {
|
if ((m_rfState == RPT_RF_STATE::AUDIO) || (m_rfState == RPT_RF_STATE::DATA)) {
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_rfSlowData.start();
|
m_rfSlowData.start();
|
||||||
|
|
@ -369,17 +369,17 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
m_rfSlowData.peakSlowData(data + 1U, m_rfN);
|
m_rfSlowData.peakSlowData(data + 1U, m_rfN);
|
||||||
unsigned char type = m_rfSlowData.getType();
|
unsigned char type = m_rfSlowData.getType();
|
||||||
|
|
||||||
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN) {
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN) {
|
||||||
LogMessage("D-Star, starting fast data mode");
|
LogMessage("D-Star, starting fast data mode");
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_DATA) {
|
if (m_rfState == RPT_RF_STATE::DATA) {
|
||||||
LogDebug("D-Star, fast data sequence no. %u", m_rfN);
|
LogDebug("D-Star, fast data sequence no. %u", m_rfN);
|
||||||
|
|
||||||
m_rfBits += 48U;
|
m_rfBits += 48U;
|
||||||
|
|
@ -398,12 +398,12 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
unsigned char type = m_rfSlowData.getType();
|
unsigned char type = m_rfSlowData.getType();
|
||||||
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_END) {
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_END) {
|
||||||
LogMessage("D-Star, leaving fast data mode");
|
LogMessage("D-Star, leaving fast data mode");
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfN = (m_rfN + 1U) % 21U;
|
m_rfN = (m_rfN + 1U) % 21U;
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
} else if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
// Send the RSSI data to the display
|
// Send the RSSI data to the display
|
||||||
if (m_rfN == 0U)
|
if (m_rfN == 0U)
|
||||||
m_display->writeDStarRSSI(m_rssi);
|
m_display->writeDStarRSSI(m_rssi);
|
||||||
|
|
@ -438,7 +438,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_rfN = (m_rfN + 1U) % 21U;
|
m_rfN = (m_rfN + 1U) % 21U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LATE_ENTRY) {
|
if (m_rfState == RPT_RF_STATE::LATE_ENTRY) {
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_rfSlowData.reset();
|
m_rfSlowData.reset();
|
||||||
|
|
@ -461,7 +461,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
// Is this a transmission destined for a repeater?
|
// Is this a transmission destined for a repeater?
|
||||||
if (!m_rfHeader.isRepeater()) {
|
if (!m_rfHeader.isRepeater()) {
|
||||||
LogMessage("D-Star, non repeater RF header received from %8.8s", my1);
|
LogMessage("D-Star, non repeater RF header received from %8.8s", my1);
|
||||||
m_rfState = RS_RF_INVALID;
|
m_rfState = RPT_RF_STATE::INVALID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,19 +471,19 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
// Is it for us?
|
// Is it for us?
|
||||||
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) {
|
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) {
|
||||||
LogMessage("D-Star, received RF header for wrong repeater (%8.8s) from %8.8s", callsign, my1);
|
LogMessage("D-Star, received RF header for wrong repeater (%8.8s) from %8.8s", callsign, my1);
|
||||||
m_rfState = RS_RF_INVALID;
|
m_rfState = RPT_RF_STATE::INVALID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0 && !(std::find_if(m_whiteList.begin(), m_whiteList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_whiteList.end())) {
|
if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0 && !(std::find_if(m_whiteList.begin(), m_whiteList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_whiteList.end())) {
|
||||||
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) {
|
if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) {
|
||||||
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -564,9 +564,9 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
writeQueueDataRF(data);
|
writeQueueDataRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
|
||||||
m_display->writeDStarRSSI(m_rssi);
|
m_display->writeDStarRSSI(m_rssi);
|
||||||
m_display->writeDStarBER(float(errors) / 0.48F);
|
m_display->writeDStarBER(float(errors) / 0.48F);
|
||||||
|
|
@ -600,11 +600,11 @@ unsigned int CDStarControl::readModem(unsigned char* data)
|
||||||
|
|
||||||
void CDStarControl::writeEndRF()
|
void CDStarControl::writeEndRF()
|
||||||
{
|
{
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_display->clearDStar();
|
m_display->clearDStar();
|
||||||
|
|
||||||
m_ackTimer.start();
|
m_ackTimer.start();
|
||||||
|
|
@ -616,7 +616,7 @@ void CDStarControl::writeEndRF()
|
||||||
|
|
||||||
void CDStarControl::writeEndNet()
|
void CDStarControl::writeEndNet()
|
||||||
{
|
{
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_lastFrameValid = false;
|
m_lastFrameValid = false;
|
||||||
|
|
||||||
|
|
@ -646,7 +646,7 @@ void CDStarControl::writeNetwork()
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA)) && (m_netState == RS_NET_IDLE))
|
if (((m_rfState == RPT_RF_STATE::AUDIO) || (m_rfState == RPT_RF_STATE::DATA)) && (m_netState == RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
@ -654,7 +654,7 @@ void CDStarControl::writeNetwork()
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_HEADER) {
|
if (type == TAG_HEADER) {
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CDStarHeader header(data + 1U);
|
CDStarHeader header(data + 1U);
|
||||||
|
|
@ -698,12 +698,12 @@ void CDStarControl::writeNetwork()
|
||||||
openFile();
|
openFile();
|
||||||
writeFile(data + 1U, length - 1U);
|
writeFile(data + 1U, length - 1U);
|
||||||
#endif
|
#endif
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
|
|
||||||
LINK_STATUS status = LS_NONE;
|
LINK_STATUS status = LINK_STATUS::NONE;
|
||||||
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
m_network->getStatus(status, reflector);
|
m_network->getStatus(status, reflector);
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK) {
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK)) {
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "N", (char*) reflector);
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "N", (char*) reflector);
|
||||||
LogMessage("D-Star, received network header from %8.8s/%4.4s to %8.8s via %8.8s", my1, my2, your, reflector);
|
LogMessage("D-Star, received network header from %8.8s/%4.4s to %8.8s via %8.8s", my1, my2, your, reflector);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -713,7 +713,7 @@ void CDStarControl::writeNetwork()
|
||||||
|
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
} else if (type == TAG_EOT) {
|
} else if (type == TAG_EOT) {
|
||||||
if ((m_netState != RS_NET_AUDIO) && (m_netState != RS_NET_DATA))
|
if ((m_netState != RPT_NET_STATE::AUDIO) && (m_netState != RPT_NET_STATE::DATA))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
writeQueueEOTNet();
|
writeQueueEOTNet();
|
||||||
|
|
@ -737,7 +737,7 @@ void CDStarControl::writeNetwork()
|
||||||
|
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
} else if (type == TAG_DATA) {
|
} else if (type == TAG_DATA) {
|
||||||
if ((m_netState == RS_NET_AUDIO) || (m_netState == RS_NET_DATA)) {
|
if ((m_netState == RPT_NET_STATE::AUDIO) || (m_netState == RPT_NET_STATE::DATA)) {
|
||||||
unsigned char n = data[1U];
|
unsigned char n = data[1U];
|
||||||
|
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
|
|
@ -746,17 +746,17 @@ void CDStarControl::writeNetwork()
|
||||||
} else {
|
} else {
|
||||||
m_netSlowData.peakSlowData(data + 1U, n);
|
m_netSlowData.peakSlowData(data + 1U, n);
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
unsigned char type = m_netSlowData.getType();
|
unsigned char type = m_netSlowData.getType();
|
||||||
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN) {
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN) {
|
||||||
LogMessage("D-Star, starting fast data mode");
|
LogMessage("D-Star, starting fast data mode");
|
||||||
m_netState = RS_NET_DATA;
|
m_netState = RPT_NET_STATE::DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
unsigned char n = data[1U];
|
unsigned char n = data[1U];
|
||||||
|
|
||||||
unsigned int errors = 0U;
|
unsigned int errors = 0U;
|
||||||
|
|
@ -796,7 +796,7 @@ void CDStarControl::writeNetwork()
|
||||||
writeQueueDataNet(data + 1U);
|
writeQueueDataNet(data + 1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_DATA) {
|
if (m_netState == RPT_NET_STATE::DATA) {
|
||||||
m_netN = data[1U];
|
m_netN = data[1U];
|
||||||
|
|
||||||
data[1U] = TAG_DATA;
|
data[1U] = TAG_DATA;
|
||||||
|
|
@ -814,7 +814,7 @@ void CDStarControl::writeNetwork()
|
||||||
unsigned char type = m_netSlowData.getType();
|
unsigned char type = m_netSlowData.getType();
|
||||||
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_END) {
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_END) {
|
||||||
LogMessage("D-Star, leaving fast data mode");
|
LogMessage("D-Star, leaving fast data mode");
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -855,7 +855,7 @@ void CDStarControl::clock()
|
||||||
m_rfTimeoutTimer.clock(ms);
|
m_rfTimeoutTimer.clock(ms);
|
||||||
m_netTimeoutTimer.clock(ms);
|
m_netTimeoutTimer.clock(ms);
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
|
|
@ -870,7 +870,7 @@ void CDStarControl::clock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only insert silence on audio data
|
// Only insert silence on audio data
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
m_packetTimer.clock(ms);
|
m_packetTimer.clock(ms);
|
||||||
|
|
||||||
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
||||||
|
|
@ -894,7 +894,7 @@ void CDStarControl::writeQueueHeaderRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
|
@ -917,7 +917,7 @@ void CDStarControl::writeQueueDataRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
|
@ -938,7 +938,7 @@ void CDStarControl::writeQueueDataRF(const unsigned char *data)
|
||||||
|
|
||||||
void CDStarControl::writeQueueEOTRF()
|
void CDStarControl::writeQueueEOTRF()
|
||||||
{
|
{
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
|
@ -1028,7 +1028,7 @@ void CDStarControl::writeNetworkHeaderRF(const unsigned char* data)
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_network->writeHeader(data + 1U, DSTAR_HEADER_LENGTH_BYTES, m_netState != RS_NET_IDLE);
|
m_network->writeHeader(data + 1U, DSTAR_HEADER_LENGTH_BYTES, m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeNetworkDataRF(const unsigned char* data, unsigned int errors, bool end)
|
void CDStarControl::writeNetworkDataRF(const unsigned char* data, unsigned int errors, bool end)
|
||||||
|
|
@ -1042,7 +1042,7 @@ void CDStarControl::writeNetworkDataRF(const unsigned char* data, unsigned int e
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_network->writeData(data + 1U, DSTAR_FRAME_LENGTH_BYTES, errors, end, m_netState != RS_NET_IDLE);
|
m_network->writeData(data + 1U, DSTAR_FRAME_LENGTH_BYTES, errors, end, m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDStarControl::openFile()
|
bool CDStarControl::openFile()
|
||||||
|
|
@ -1184,20 +1184,20 @@ void CDStarControl::sendAck()
|
||||||
|
|
||||||
writeQueueDataRF(DSTAR_NULL_FRAME_SYNC_BYTES);
|
writeQueueDataRF(DSTAR_NULL_FRAME_SYNC_BYTES);
|
||||||
|
|
||||||
LINK_STATUS status = LS_NONE;
|
LINK_STATUS status = LINK_STATUS::NONE;
|
||||||
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
m_network->getStatus(status, reflector);
|
m_network->getStatus(status, reflector);
|
||||||
|
|
||||||
char text[40U];
|
char text[40U];
|
||||||
if (m_ackMessage == DSTAR_ACK_RSSI && m_rssi != 0) {
|
if ((m_ackMessage == DSTAR_ACK::RSSI) && (m_rssi != 0U)) {
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK) {
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK)) {
|
||||||
CUtils::removeChar(reflector, ' ');//remove space from reflector so all nicely fits onto 20 chars in case rssi < 99dBm
|
CUtils::removeChar(reflector, ' ');//remove space from reflector so all nicely fits onto 20 chars in case rssi < 99dBm
|
||||||
::sprintf(text, "%-8.8s %.1f%% -%udBm ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
::sprintf(text, "%-8.8s %.1f%% -%udBm ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
||||||
} else {
|
} else {
|
||||||
::sprintf(text, "BER:%.1f%% -%udBm ", float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
::sprintf(text, "BER:%.1f%% -%udBm ", float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
||||||
}
|
}
|
||||||
} else if (m_ackMessage == DSTAR_ACK_SMETER && m_rssi != 0) {
|
} else if ((m_ackMessage == DSTAR_ACK::SMETER) && (m_rssi != 0U)) {
|
||||||
unsigned int signal, plus;
|
unsigned int signal, plus;
|
||||||
char signalText[15U];
|
char signalText[15U];
|
||||||
CSMeter::getSignal(m_aveRSSI / m_rssiCount, signal, plus);
|
CSMeter::getSignal(m_aveRSSI / m_rssiCount, signal, plus);
|
||||||
|
|
@ -1206,12 +1206,12 @@ void CDStarControl::sendAck()
|
||||||
else
|
else
|
||||||
::sprintf(signalText, "S%u", signal);
|
::sprintf(signalText, "S%u", signal);
|
||||||
|
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK))
|
||||||
::sprintf(text, "%-8.8s %.1f%% %s ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
::sprintf(text, "%-8.8s %.1f%% %s ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
||||||
else
|
else
|
||||||
::sprintf(text, "BER:%.1f%% %s ", float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
::sprintf(text, "BER:%.1f%% %s ", float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
||||||
} else {
|
} else {
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK))
|
||||||
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));
|
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
else
|
else
|
||||||
::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits));
|
::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
@ -1249,20 +1249,20 @@ void CDStarControl::sendError()
|
||||||
|
|
||||||
writeQueueDataRF(DSTAR_NULL_FRAME_SYNC_BYTES);
|
writeQueueDataRF(DSTAR_NULL_FRAME_SYNC_BYTES);
|
||||||
|
|
||||||
LINK_STATUS status = LS_NONE;
|
LINK_STATUS status = LINK_STATUS::NONE;
|
||||||
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
m_network->getStatus(status, reflector);
|
m_network->getStatus(status, reflector);
|
||||||
|
|
||||||
char text[40U];
|
char text[40U];
|
||||||
if (m_ackMessage == DSTAR_ACK_RSSI && m_rssi != 0) {
|
if ((m_ackMessage == DSTAR_ACK::RSSI) && (m_rssi != 0U)) {
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK) {
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK)) {
|
||||||
CUtils::removeChar(reflector, ' ');//remove space from reflector so all nicely fits onto 20 chars in case rssi < 99dBm
|
CUtils::removeChar(reflector, ' ');//remove space from reflector so all nicely fits onto 20 chars in case rssi < 99dBm
|
||||||
::sprintf(text, "%-8.8s %.1f%% -%udBm ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
::sprintf(text, "%-8.8s %.1f%% -%udBm ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
||||||
} else {
|
} else {
|
||||||
::sprintf(text, "BER:%.1f%% -%udBm ", float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
::sprintf(text, "BER:%.1f%% -%udBm ", float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
|
||||||
}
|
}
|
||||||
} else if (m_ackMessage == DSTAR_ACK_SMETER && m_rssi != 0) {
|
} else if ((m_ackMessage == DSTAR_ACK::SMETER) && (m_rssi != 0U)) {
|
||||||
unsigned int signal, plus;
|
unsigned int signal, plus;
|
||||||
char signalText[15U];
|
char signalText[15U];
|
||||||
CSMeter::getSignal(m_aveRSSI / m_rssiCount, signal, plus);
|
CSMeter::getSignal(m_aveRSSI / m_rssiCount, signal, plus);
|
||||||
|
|
@ -1271,12 +1271,12 @@ void CDStarControl::sendError()
|
||||||
else
|
else
|
||||||
::sprintf(signalText, "S%u", signal);
|
::sprintf(signalText, "S%u", signal);
|
||||||
|
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK))
|
||||||
::sprintf(text, "%-8.8s %.1f%% %s ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
::sprintf(text, "%-8.8s %.1f%% %s ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
||||||
else
|
else
|
||||||
::sprintf(text, "BER:%.1f%% %s ", float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
::sprintf(text, "BER:%.1f%% %s ", float(m_rfErrs * 100U) / float(m_rfBits), signalText);
|
||||||
} else {
|
} else {
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
|
if ((status == LINK_STATUS::LINKED_DEXTRA) || (status == LINK_STATUS::LINKED_DPLUS) || (status == LINK_STATUS::LINKED_DCS) || (status == LINK_STATUS::LINKED_CCS) || (status == LINK_STATUS::LINKED_LOOPBACK))
|
||||||
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));
|
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
else
|
else
|
||||||
::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits));
|
::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
@ -1296,7 +1296,7 @@ void CDStarControl::sendError()
|
||||||
|
|
||||||
bool CDStarControl::isBusy() const
|
bool CDStarControl::isBusy() const
|
||||||
{
|
{
|
||||||
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
|
return (m_rfState != RPT_RF_STATE::LISTENING) || (m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::enable(bool enabled)
|
void CDStarControl::enable(bool enabled)
|
||||||
|
|
@ -1305,12 +1305,12 @@ void CDStarControl::enable(bool enabled)
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
|
|
||||||
// Reset the RF section
|
// Reset the RF section
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
// Reset the networking section
|
// Reset the networking section
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_lastFrameValid = false;
|
m_lastFrameValid = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
class CDStarControl {
|
class CDStarControl {
|
||||||
public:
|
public:
|
||||||
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, DSTAR_ACK_MESSAGE ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, DSTAR_ACK ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
||||||
~CDStarControl();
|
~CDStarControl();
|
||||||
|
|
||||||
bool writeModem(unsigned char* data, unsigned int len);
|
bool writeModem(unsigned char* data, unsigned int len);
|
||||||
|
|
@ -55,7 +55,7 @@ private:
|
||||||
unsigned char* m_gateway;
|
unsigned char* m_gateway;
|
||||||
bool m_selfOnly;
|
bool m_selfOnly;
|
||||||
bool m_ackReply;
|
bool m_ackReply;
|
||||||
DSTAR_ACK_MESSAGE m_ackMessage;
|
DSTAR_ACK m_ackMessage;
|
||||||
bool m_errorReply;
|
bool m_errorReply;
|
||||||
bool m_remoteGateway;
|
bool m_remoteGateway;
|
||||||
std::vector<std::string> m_blackList;
|
std::vector<std::string> m_blackList;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2018,2019,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2018,2019,2021,2025 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
|
||||||
|
|
@ -66,7 +66,7 @@ const unsigned char DSTAR_URGENT_MASK = 0x08U;
|
||||||
const unsigned char DSTAR_REPEATER_CONTROL = 0x07U;
|
const unsigned char DSTAR_REPEATER_CONTROL = 0x07U;
|
||||||
const unsigned char DSTAR_AUTO_REPLY = 0x06U;
|
const unsigned char DSTAR_AUTO_REPLY = 0x06U;
|
||||||
const unsigned char DSTAR_RESEND_REQUESTED = 0x04U;
|
const unsigned char DSTAR_RESEND_REQUESTED = 0x04U;
|
||||||
const unsigned char DSTAR_ACK_FLAG = 0x03U;
|
const unsigned char FLAG = 0x03U;
|
||||||
const unsigned char DSTAR_NO_RESPONSE = 0x02U;
|
const unsigned char DSTAR_NO_RESPONSE = 0x02U;
|
||||||
const unsigned char DSTAR_RELAY_UNAVAILABLE = 0x01U;
|
const unsigned char DSTAR_RELAY_UNAVAILABLE = 0x01U;
|
||||||
|
|
||||||
|
|
@ -77,19 +77,19 @@ const unsigned char DSTAR_DTMF_SIG[] = { 0x82U, 0x08U, 0x20U, 0x82U, 0x00U, 0x0
|
||||||
|
|
||||||
const unsigned int DSTAR_FRAME_TIME = 20U;
|
const unsigned int DSTAR_FRAME_TIME = 20U;
|
||||||
|
|
||||||
enum LINK_STATUS {
|
enum class LINK_STATUS {
|
||||||
LS_NONE,
|
NONE,
|
||||||
LS_PENDING_IRCDDB,
|
PENDING_IRCDDB,
|
||||||
LS_LINKING_LOOPBACK,
|
LINKING_LOOPBACK,
|
||||||
LS_LINKING_DEXTRA,
|
LINKING_DEXTRA,
|
||||||
LS_LINKING_DPLUS,
|
LINKING_DPLUS,
|
||||||
LS_LINKING_DCS,
|
LINKING_DCS,
|
||||||
LS_LINKING_CCS,
|
LINKING_CCS,
|
||||||
LS_LINKED_LOOPBACK,
|
LINKED_LOOPBACK,
|
||||||
LS_LINKED_DEXTRA,
|
LINKED_DEXTRA,
|
||||||
LS_LINKED_DPLUS,
|
LINKED_DPLUS,
|
||||||
LS_LINKED_DCS,
|
LINKED_DCS,
|
||||||
LS_LINKED_CCS
|
LINKED_CCS
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2014,2016,2019,2020,2021,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2014,2016,2019,2020,2021,2024,2025 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
|
||||||
|
|
@ -43,7 +43,7 @@ m_outSeq(0U),
|
||||||
m_inId(0U),
|
m_inId(0U),
|
||||||
m_buffer(1000U, "D-Star Network"),
|
m_buffer(1000U, "D-Star Network"),
|
||||||
m_pollTimer(1000U, 60U),
|
m_pollTimer(1000U, 60U),
|
||||||
m_linkStatus(LS_NONE),
|
m_linkStatus(LINK_STATUS::NONE),
|
||||||
m_linkReflector(NULL),
|
m_linkReflector(NULL),
|
||||||
m_random()
|
m_random()
|
||||||
{
|
{
|
||||||
|
|
@ -166,7 +166,7 @@ bool CDStarNetwork::writePoll(const char* text)
|
||||||
|
|
||||||
buffer[4] = 0x0AU; // Poll with text
|
buffer[4] = 0x0AU; // Poll with text
|
||||||
|
|
||||||
unsigned int length = ::strlen(text);
|
unsigned int length = (unsigned int)::strlen(text);
|
||||||
|
|
||||||
// Include the nul at the end also
|
// Include the nul at the end also
|
||||||
::memcpy(buffer + 5U, text, length + 1U);
|
::memcpy(buffer + 5U, text, length + 1U);
|
||||||
|
|
|
||||||
82
Defines.h
82
Defines.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018,2020,2021,2025 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
|
||||||
|
|
@ -42,56 +42,56 @@ const unsigned char TAG_EOT = 0x03U;
|
||||||
|
|
||||||
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
|
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
|
||||||
|
|
||||||
enum HW_TYPE {
|
enum class HW_TYPE {
|
||||||
HWT_MMDVM,
|
MMDVM,
|
||||||
HWT_DVMEGA,
|
DVMEGA,
|
||||||
HWT_MMDVM_ZUMSPOT,
|
MMDVM_ZUMSPOT,
|
||||||
HWT_MMDVM_HS_HAT,
|
MMDVM_HS_HAT,
|
||||||
HWT_MMDVM_HS_DUAL_HAT,
|
MMDVM_HS_DUAL_HAT,
|
||||||
HWT_NANO_HOTSPOT,
|
NANO_HOTSPOT,
|
||||||
HWT_NANO_DV,
|
NANO_DV,
|
||||||
HWT_D2RG_MMDVM_HS,
|
D2RG_MMDVM_HS,
|
||||||
HWT_MMDVM_HS,
|
MMDVM_HS,
|
||||||
HWT_OPENGD77_HS,
|
OPENGD77_HS,
|
||||||
HWT_SKYBRIDGE,
|
SKYBRIDGE,
|
||||||
HWT_UNKNOWN
|
UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RPT_RF_STATE {
|
enum class RPT_RF_STATE {
|
||||||
RS_RF_LISTENING,
|
LISTENING,
|
||||||
RS_RF_LATE_ENTRY,
|
LATE_ENTRY,
|
||||||
RS_RF_AUDIO,
|
AUDIO,
|
||||||
RS_RF_DATA_AUDIO,
|
DATA_AUDIO,
|
||||||
RS_RF_DATA,
|
DATA,
|
||||||
RS_RF_REJECTED,
|
REJECTED,
|
||||||
RS_RF_INVALID
|
INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RPT_NET_STATE {
|
enum class RPT_NET_STATE {
|
||||||
RS_NET_IDLE,
|
IDLE,
|
||||||
RS_NET_AUDIO,
|
AUDIO,
|
||||||
RS_NET_DATA_AUDIO,
|
DATA_AUDIO,
|
||||||
RS_NET_DATA
|
DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DMR_BEACONS {
|
enum class DMR_BEACONS {
|
||||||
DMR_BEACONS_OFF,
|
OFF,
|
||||||
DMR_BEACONS_NETWORK,
|
NETWORK,
|
||||||
DMR_BEACONS_TIMED
|
TIMED
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DMR_OVCM_TYPES {
|
enum class DMR_OVCM {
|
||||||
DMR_OVCM_OFF,
|
OFF,
|
||||||
DMR_OVCM_RX_ON,
|
RX_ON,
|
||||||
DMR_OVCM_TX_ON,
|
TX_ON,
|
||||||
DMR_OVCM_ON,
|
ON,
|
||||||
DMR_OVCM_FORCE_OFF
|
FORCE_OFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DSTAR_ACK_MESSAGE {
|
enum class DSTAR_ACK {
|
||||||
DSTAR_ACK_BER,
|
BER,
|
||||||
DSTAR_ACK_RSSI,
|
RSSI,
|
||||||
DSTAR_ACK_SMETER
|
SMETER
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020,2021,2023,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2020,2021,2023,2024,2025 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
|
||||||
|
|
@ -35,7 +35,7 @@ const unsigned int BUFFER_LENGTH = 1500U;
|
||||||
|
|
||||||
CFMNetwork::CFMNetwork(const std::string& callsign, const std::string& protocol, const std::string& localAddress, unsigned short localPort, const std::string& gatewayAddress, unsigned short gatewayPort, unsigned int sampleRate, const std::string& squelchFile, bool debug) :
|
CFMNetwork::CFMNetwork(const std::string& callsign, const std::string& protocol, const std::string& localAddress, unsigned short localPort, const std::string& gatewayAddress, unsigned short gatewayPort, unsigned int sampleRate, const std::string& squelchFile, bool debug) :
|
||||||
m_callsign(callsign),
|
m_callsign(callsign),
|
||||||
m_protocol(FMNP_USRP),
|
m_protocol(FM_NETWORK_PROTOCOL::USRP),
|
||||||
m_socket(localAddress, localPort),
|
m_socket(localAddress, localPort),
|
||||||
m_addr(),
|
m_addr(),
|
||||||
m_addrLen(0U),
|
m_addrLen(0U),
|
||||||
|
|
@ -65,9 +65,9 @@ m_fp(NULL)
|
||||||
m_callsign = callsign.substr(0U, pos);
|
m_callsign = callsign.substr(0U, pos);
|
||||||
|
|
||||||
if (protocol == "RAW")
|
if (protocol == "RAW")
|
||||||
m_protocol = FMNP_RAW;
|
m_protocol = FM_NETWORK_PROTOCOL::RAW;
|
||||||
else
|
else
|
||||||
m_protocol = FMNP_USRP;
|
m_protocol = FM_NETWORK_PROTOCOL::USRP;
|
||||||
|
|
||||||
#if defined(HAS_SRC)
|
#if defined(HAS_SRC)
|
||||||
m_resampler = ::src_new(SRC_SINC_FASTEST, 1, &m_error);
|
m_resampler = ::src_new(SRC_SINC_FASTEST, 1, &m_error);
|
||||||
|
|
@ -90,7 +90,7 @@ bool CFMNetwork::open()
|
||||||
|
|
||||||
LogMessage("Opening FM network connection");
|
LogMessage("Opening FM network connection");
|
||||||
|
|
||||||
if (m_protocol == FMNP_RAW) {
|
if (m_protocol == FM_NETWORK_PROTOCOL::RAW) {
|
||||||
if (!m_squelchFile.empty()) {
|
if (!m_squelchFile.empty()) {
|
||||||
m_fp = ::fopen(m_squelchFile.c_str(), "wb");
|
m_fp = ::fopen(m_squelchFile.c_str(), "wb");
|
||||||
if (m_fp == NULL) {
|
if (m_fp == NULL) {
|
||||||
|
|
@ -105,7 +105,7 @@ bool CFMNetwork::open()
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(HAS_SRC)
|
#if !defined(HAS_SRC)
|
||||||
if ((m_protocol == FMNP_RAW) && (m_sampleRate != MMDVM_SAMPLERATE)) {
|
if ((m_protocol == FM_NETWORK_PROTOCOL::RAW) && (m_sampleRate != MMDVM_SAMPLERATE)) {
|
||||||
LogError("The resampler needed for non-native sample rates has not been included");
|
LogError("The resampler needed for non-native sample rates has not been included");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -119,9 +119,9 @@ bool CFMNetwork::writeData(const float* data, unsigned int nSamples)
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
assert(nSamples > 0U);
|
assert(nSamples > 0U);
|
||||||
|
|
||||||
if (m_protocol == FMNP_USRP)
|
if (m_protocol == FM_NETWORK_PROTOCOL::USRP)
|
||||||
return writeUSRPData(data, nSamples);
|
return writeUSRPData(data, nSamples);
|
||||||
else if (m_protocol == FMNP_RAW)
|
else if (m_protocol == FM_NETWORK_PROTOCOL::RAW)
|
||||||
return writeRawData(data, nSamples);
|
return writeRawData(data, nSamples);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -264,7 +264,7 @@ bool CFMNetwork::writeRawData(const float* in, unsigned int nIn)
|
||||||
|
|
||||||
bool CFMNetwork::writeEnd()
|
bool CFMNetwork::writeEnd()
|
||||||
{
|
{
|
||||||
if (m_protocol == FMNP_USRP)
|
if (m_protocol == FM_NETWORK_PROTOCOL::USRP)
|
||||||
return writeUSRPEnd();
|
return writeUSRPEnd();
|
||||||
else
|
else
|
||||||
return writeRawEnd();
|
return writeRawEnd();
|
||||||
|
|
@ -366,13 +366,13 @@ void CFMNetwork::clock(unsigned int ms)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check if the data is for us
|
// Check if the data is for us
|
||||||
if (m_protocol == FMNP_USRP) {
|
if (m_protocol == FM_NETWORK_PROTOCOL::USRP) {
|
||||||
if (!CUDPSocket::match(addr, m_addr, IMT_ADDRESS_AND_PORT)) {
|
if (!CUDPSocket::match(addr, m_addr, IPMATCHTYPE::IMT_ADDREAND_PORT)) {
|
||||||
LogMessage("FM packet received from an invalid source");
|
LogMessage("FM packet received from an invalid source");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!CUDPSocket::match(addr, m_addr, IMT_ADDRESS_ONLY)) {
|
if (!CUDPSocket::match(addr, m_addr, IPMATCHTYPE::IMT_ADDREONLY)) {
|
||||||
LogMessage("FM packet received from an invalid source");
|
LogMessage("FM packet received from an invalid source");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -384,7 +384,7 @@ void CFMNetwork::clock(unsigned int ms)
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
CUtils::dump(1U, "FM Network Data Received", buffer, length);
|
CUtils::dump(1U, "FM Network Data Received", buffer, length);
|
||||||
|
|
||||||
if (m_protocol == FMNP_USRP) {
|
if (m_protocol == FM_NETWORK_PROTOCOL::USRP) {
|
||||||
// Invalid packet type?
|
// Invalid packet type?
|
||||||
if (::memcmp(buffer, "USRP", 4U) != 0)
|
if (::memcmp(buffer, "USRP", 4U) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -400,7 +400,7 @@ void CFMNetwork::clock(unsigned int ms)
|
||||||
|
|
||||||
if (type == 0U)
|
if (type == 0U)
|
||||||
m_buffer.addData(buffer + 32U, length - 32U);
|
m_buffer.addData(buffer + 32U, length - 32U);
|
||||||
} else if (m_protocol == FMNP_RAW) {
|
} else if (m_protocol == FM_NETWORK_PROTOCOL::RAW) {
|
||||||
m_buffer.addData(buffer, length);
|
m_buffer.addData(buffer, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -415,7 +415,7 @@ unsigned int CFMNetwork::readData(float* out, unsigned int nOut)
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
||||||
#if defined(HAS_SRC)
|
#if defined(HAS_SRC)
|
||||||
if ((m_protocol == FMNP_RAW) && (m_sampleRate != MMDVM_SAMPLERATE)) {
|
if ((m_protocol == RAW) && (m_sampleRate != MMDVM_SAMPLERATE)) {
|
||||||
unsigned int nIn = (nOut * m_sampleRate) / MMDVM_SAMPLERATE;
|
unsigned int nIn = (nOut * m_sampleRate) / MMDVM_SAMPLERATE;
|
||||||
|
|
||||||
if (bytes < nIn) {
|
if (bytes < nIn) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020,2021,2023,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2020,2021,2023,2024,2025 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
|
||||||
|
|
@ -29,9 +29,9 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum FM_NETWORK_PROTOCOL {
|
enum class FM_NETWORK_PROTOCOL {
|
||||||
FMNP_USRP,
|
USRP,
|
||||||
FMNP_RAW
|
RAW
|
||||||
};
|
};
|
||||||
|
|
||||||
class CFMNetwork {
|
class CFMNetwork {
|
||||||
|
|
|
||||||
16
LCDproc.cpp
16
LCDproc.cpp
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 by Tony Corbett G0WFV
|
* Copyright (C) 2016,2017,2018 by Tony Corbett G0WFV
|
||||||
* Copyright (C) 2018,2020,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2018,2020,2024,2025 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
|
||||||
|
|
@ -78,7 +78,11 @@
|
||||||
|
|
||||||
#define BUFFER_MAX_LEN 128
|
#define BUFFER_MAX_LEN 128
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
SOCKET m_socketfd;
|
||||||
|
#else
|
||||||
int m_socketfd;
|
int m_socketfd;
|
||||||
|
#endif
|
||||||
char m_buffer[BUFFER_MAX_LEN];
|
char m_buffer[BUFFER_MAX_LEN];
|
||||||
fd_set m_readfds, m_writefds;
|
fd_set m_readfds, m_writefds;
|
||||||
struct timeval m_timeout;
|
struct timeval m_timeout;
|
||||||
|
|
@ -141,7 +145,7 @@ bool CLCDproc::open()
|
||||||
LogError("LCDproc, cannot lookup server");
|
LogError("LCDproc, cannot lookup server");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(&serverAddress, res->ai_addr, addrlen = res->ai_addrlen);
|
memcpy(&serverAddress, res->ai_addr, addrlen = (unsigned int)res->ai_addrlen);
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
|
|
||||||
/* Lookup the client address (random port - need to specify manual port from ini file) */
|
/* Lookup the client address (random port - need to specify manual port from ini file) */
|
||||||
|
|
@ -671,7 +675,7 @@ void CLCDproc::clockInt(unsigned int ms)
|
||||||
* exceptfds = we are not waiting for exception fds
|
* exceptfds = we are not waiting for exception fds
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (select(m_socketfd + 1, &m_readfds, NULL, NULL, &m_timeout) == -1) {
|
if (select(int(m_socketfd) + 1, &m_readfds, NULL, NULL, &m_timeout) == -1) {
|
||||||
LogError("LCDproc, error on select");
|
LogError("LCDproc, error on select");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -767,7 +771,11 @@ void CLCDproc::close()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
int CLCDproc::socketPrintf(SOCKET fd, const char* format, ...)
|
||||||
|
#else
|
||||||
int CLCDproc::socketPrintf(int fd, const char *format, ...)
|
int CLCDproc::socketPrintf(int fd, const char *format, ...)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
char buf[BUFFER_MAX_LEN];
|
char buf[BUFFER_MAX_LEN];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
@ -790,7 +798,7 @@ int CLCDproc::socketPrintf(int fd, const char *format, ...)
|
||||||
m_timeout.tv_sec = 0;
|
m_timeout.tv_sec = 0;
|
||||||
m_timeout.tv_usec = 0;
|
m_timeout.tv_usec = 0;
|
||||||
|
|
||||||
if (select(m_socketfd + 1, NULL, &m_writefds, NULL, &m_timeout) == -1)
|
if (select(int(m_socketfd) + 1, NULL, &m_writefds, NULL, &m_timeout) == -1)
|
||||||
LogError("LCDproc, error on select");
|
LogError("LCDproc, error on select");
|
||||||
|
|
||||||
if (FD_ISSET(m_socketfd, &m_writefds)) {
|
if (FD_ISSET(m_socketfd, &m_writefds)) {
|
||||||
|
|
|
||||||
11
LCDproc.h
11
LCDproc.h
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017 by Tony Corbett G0WFV
|
* Copyright (C) 2016,2017 by Tony Corbett G0WFV
|
||||||
* Copyright (C) 2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2018,2020,2025 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
|
||||||
|
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <Winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
class CLCDproc : public CDisplay
|
class CLCDproc : public CDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -89,7 +94,11 @@ private:
|
||||||
unsigned int m_rssiCount1;
|
unsigned int m_rssiCount1;
|
||||||
unsigned int m_rssiCount2;
|
unsigned int m_rssiCount2;
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
int socketPrintf(SOCKET fd, const char* format, ...);
|
||||||
|
#else
|
||||||
int socketPrintf(int fd, const char *format, ...);
|
int socketPrintf(int fd, const char *format, ...);
|
||||||
|
#endif
|
||||||
void defineScreens();
|
void defineScreens();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
4
Log.cpp
4
Log.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020,2025 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
|
||||||
|
|
@ -167,7 +167,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, fmt);
|
va_start(vl, fmt);
|
||||||
|
|
||||||
::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl);
|
::vsnprintf(buffer + ::strlen(buffer), 500 - ::strlen(buffer), fmt, vl);
|
||||||
|
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020,2021,2023 Jonathan Naylor, G4KLX
|
* Copyright (C) 2020,2021,2023,2025 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
|
||||||
|
|
@ -68,8 +68,8 @@ m_duplex(duplex),
|
||||||
m_queue(5000U, "M17 Control"),
|
m_queue(5000U, "M17 Control"),
|
||||||
m_source(),
|
m_source(),
|
||||||
m_dest(),
|
m_dest(),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RPT_RF_STATE::LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RPT_NET_STATE::IDLE),
|
||||||
m_rfTimeoutTimer(1000U, timeout),
|
m_rfTimeoutTimer(1000U, timeout),
|
||||||
m_netTimeoutTimer(1000U, timeout),
|
m_netTimeoutTimer(1000U, timeout),
|
||||||
m_networkWatchdog(1000U, 0U, 1500U),
|
m_networkWatchdog(1000U, 0U, 1500U),
|
||||||
|
|
@ -121,7 +121,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
|
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO)) {
|
if (type == TAG_LOST && (m_rfState == RPT_RF_STATE::AUDIO || m_rfState == RPT_RF_STATE::DATA_AUDIO)) {
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("M17, transmission lost from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_source.c_str(), m_dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("M17, transmission lost from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_source.c_str(), m_dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
|
|
@ -130,18 +130,18 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_DATA) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::DATA)) {
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_REJECTED) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::REJECTED)) {
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST) {
|
if (type == TAG_LOST) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +172,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
decorrelator(data + 2U, temp);
|
decorrelator(data + 2U, temp);
|
||||||
interleaver(temp, data + 2U);
|
interleaver(temp, data + 2U);
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_HEADER) {
|
if ((m_rfState == RPT_RF_STATE::LISTENING) && (data[0U] == TAG_HEADER)) {
|
||||||
m_rfCurrentRFLSF.reset();
|
m_rfCurrentRFLSF.reset();
|
||||||
m_rfCurrentNetLSF.reset();
|
m_rfCurrentNetLSF.reset();
|
||||||
|
|
||||||
|
|
@ -212,18 +212,18 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
m_rfState = RS_RF_LATE_ENTRY;
|
m_rfState = RPT_RF_STATE::LATE_ENTRY;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_DATA) {
|
if ((m_rfState == RPT_RF_STATE::LISTENING) && (data[0U] == TAG_DATA)) {
|
||||||
m_rfState = RS_RF_LATE_ENTRY;
|
m_rfState = RPT_RF_STATE::LATE_ENTRY;
|
||||||
m_rfCurrentRFLSF.reset();
|
m_rfCurrentRFLSF.reset();
|
||||||
m_rfCurrentNetLSF.reset();
|
m_rfCurrentNetLSF.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) {
|
if ((m_rfState == RPT_RF_STATE::LATE_ENTRY) && (data[0U] == TAG_DATA)) {
|
||||||
unsigned int lich1, lich2, lich3, lich4;
|
unsigned int lich1, lich2, lich3, lich4;
|
||||||
bool valid1 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 0U, lich1);
|
bool valid1 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 0U, lich1);
|
||||||
bool valid2 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 3U, lich2);
|
bool valid2 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 3U, lich2);
|
||||||
|
|
@ -270,7 +270,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO) && data[0U] == TAG_DATA) {
|
if (((m_rfState == RPT_RF_STATE::AUDIO) || (m_rfState == RPT_RF_STATE::DATA_AUDIO)) && (data[0U] == TAG_DATA)) {
|
||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -419,7 +419,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO) && data[0U] == TAG_EOT) {
|
if (((m_rfState == RPT_RF_STATE::AUDIO) || (m_rfState == RPT_RF_STATE::DATA_AUDIO)) && (data[0U] == TAG_EOT)) {
|
||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -445,10 +445,10 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] = 0x80U;
|
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] = 0x80U;
|
||||||
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 1U] = 0x00U;
|
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 1U] = 0x00U;
|
||||||
|
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_3200_SILENCE, 8U);
|
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_3200_SILENCE, 8U);
|
||||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, M17_3200_SILENCE, 8U);
|
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, M17_3200_SILENCE, 8U);
|
||||||
} else if (m_rfState == RS_RF_DATA_AUDIO) {
|
} else if (m_rfState == RPT_RF_STATE::DATA_AUDIO) {
|
||||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_1600_SILENCE, 8U);
|
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_1600_SILENCE, 8U);
|
||||||
::memset(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, 0x00U, 8U);
|
::memset(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, 0x00U, 8U);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -490,7 +490,7 @@ unsigned int CM17Control::readModem(unsigned char* data)
|
||||||
|
|
||||||
void CM17Control::writeEndRF()
|
void CM17Control::writeEndRF()
|
||||||
{
|
{
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
|
|
@ -502,7 +502,7 @@ void CM17Control::writeEndRF()
|
||||||
m_rfCollectingLSF.reset();
|
m_rfCollectingLSF.reset();
|
||||||
m_rfCollectedLSF.reset();
|
m_rfCollectedLSF.reset();
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_display->clearM17();
|
m_display->clearM17();
|
||||||
|
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
|
|
@ -516,7 +516,7 @@ void CM17Control::writeEndRF()
|
||||||
|
|
||||||
void CM17Control::writeEndNet()
|
void CM17Control::writeEndNet()
|
||||||
{
|
{
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_netTimeoutTimer.stop();
|
m_netTimeoutTimer.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
|
|
@ -542,7 +542,7 @@ void CM17Control::writeNetwork()
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfState != RS_RF_LISTENING && m_rfState != RS_RF_LATE_ENTRY && m_netState == RS_NET_IDLE) {
|
if ((m_rfState != RPT_RF_STATE::LISTENING) && (m_rfState != RPT_RF_STATE::LATE_ENTRY) && (m_netState == RPT_NET_STATE::IDLE)) {
|
||||||
m_network->reset();
|
m_network->reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -560,7 +560,7 @@ void CM17Control::writeNetwork()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_netLSF.setNetwork(netData);
|
m_netLSF.setNetwork(netData);
|
||||||
|
|
||||||
m_source = m_netLSF.getSource();
|
m_source = m_netLSF.getSource();
|
||||||
|
|
@ -573,15 +573,15 @@ void CM17Control::writeNetwork()
|
||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case M17_DATA_TYPE_DATA:
|
case M17_DATA_TYPE_DATA:
|
||||||
LogMessage("M17, received network data transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received network data transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
||||||
m_netState = RS_NET_DATA;
|
m_netState = RPT_NET_STATE::DATA;
|
||||||
break;
|
break;
|
||||||
case M17_DATA_TYPE_VOICE:
|
case M17_DATA_TYPE_VOICE:
|
||||||
LogMessage("M17, received network voice transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received network voice transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
break;
|
break;
|
||||||
case M17_DATA_TYPE_VOICE_DATA:
|
case M17_DATA_TYPE_VOICE_DATA:
|
||||||
LogMessage("M17, received network voice + data transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received network voice + data transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
||||||
m_netState = RS_NET_DATA_AUDIO;
|
m_netState = RPT_NET_STATE::DATA_AUDIO;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogMessage("M17, received network unknown transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received network unknown transmission from %s to %s", m_source.c_str(), m_dest.c_str());
|
||||||
|
|
@ -621,7 +621,7 @@ void CM17Control::writeNetwork()
|
||||||
writeQueueNet(start);
|
writeQueueNet(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA_AUDIO) {
|
if ((m_netState == RPT_NET_STATE::AUDIO) || (m_netState == RPT_NET_STATE::DATA_AUDIO)) {
|
||||||
// Refresh the LSF every six frames in case the META field changes
|
// Refresh the LSF every six frames in case the META field changes
|
||||||
if (m_netLSFn == 0U) {
|
if (m_netLSFn == 0U) {
|
||||||
m_netLSF.setNetwork(netData);
|
m_netLSF.setNetwork(netData);
|
||||||
|
|
@ -751,7 +751,7 @@ bool CM17Control::processRFHeader(bool lateEntry)
|
||||||
unsigned char type = m_rfCurrentNetLSF.getEncryptionType();
|
unsigned char type = m_rfCurrentNetLSF.getEncryptionType();
|
||||||
if (type != M17_ENCRYPTION_TYPE_NONE) {
|
if (type != M17_ENCRYPTION_TYPE_NONE) {
|
||||||
LogMessage("M17, access attempt with encryption from %s to %s", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, access attempt with encryption from %s to %s", m_source.c_str(), m_dest.c_str());
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -760,7 +760,7 @@ bool CM17Control::processRFHeader(bool lateEntry)
|
||||||
bool ret = checkCallsign(m_source);
|
bool ret = checkCallsign(m_source);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogMessage("M17, invalid access attempt from %s to %s", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, invalid access attempt from %s to %s", m_source.c_str(), m_dest.c_str());
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -769,15 +769,15 @@ bool CM17Control::processRFHeader(bool lateEntry)
|
||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case M17_DATA_TYPE_DATA:
|
case M17_DATA_TYPE_DATA:
|
||||||
LogMessage("M17, received RF%sdata transmission from %s to %s", lateEntry ? " late entry " : " ", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received RF%sdata transmission from %s to %s", lateEntry ? " late entry " : " ", m_source.c_str(), m_dest.c_str());
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
break;
|
break;
|
||||||
case M17_DATA_TYPE_VOICE:
|
case M17_DATA_TYPE_VOICE:
|
||||||
LogMessage("M17, received RF%svoice transmission from %s to %s", lateEntry ? " late entry " : " ", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received RF%svoice transmission from %s to %s", lateEntry ? " late entry " : " ", m_source.c_str(), m_dest.c_str());
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
break;
|
break;
|
||||||
case M17_DATA_TYPE_VOICE_DATA:
|
case M17_DATA_TYPE_VOICE_DATA:
|
||||||
LogMessage("M17, received RF%svoice + data transmission from %s to %s", lateEntry ? " late entry " : " ", m_source.c_str(), m_dest.c_str());
|
LogMessage("M17, received RF%svoice + data transmission from %s to %s", lateEntry ? " late entry " : " ", m_source.c_str(), m_dest.c_str());
|
||||||
m_rfState = RS_RF_DATA_AUDIO;
|
m_rfState = RPT_RF_STATE::DATA_AUDIO;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -841,7 +841,7 @@ void CM17Control::clock(unsigned int ms)
|
||||||
m_rfTimeoutTimer.clock(ms);
|
m_rfTimeoutTimer.clock(ms);
|
||||||
m_netTimeoutTimer.clock(ms);
|
m_netTimeoutTimer.clock(ms);
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA_AUDIO) {
|
if ((m_netState == RPT_NET_STATE::AUDIO) || (m_netState == RPT_NET_STATE::DATA_AUDIO)) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
|
|
@ -855,7 +855,7 @@ void CM17Control::writeQueueRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
|
@ -966,7 +966,7 @@ void CM17Control::closeFile()
|
||||||
|
|
||||||
bool CM17Control::isBusy() const
|
bool CM17Control::isBusy() const
|
||||||
{
|
{
|
||||||
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
|
return (m_rfState != RPT_RF_STATE::LISTENING) || (m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CM17Control::enable(bool enabled)
|
void CM17Control::enable(bool enabled)
|
||||||
|
|
@ -975,12 +975,12 @@ void CM17Control::enable(bool enabled)
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
|
|
||||||
// Reset the RF section
|
// Reset the RF section
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
// Reset the networking section
|
// Reset the networking section
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_netTimeoutTimer.stop();
|
m_netTimeoutTimer.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
|
|
|
||||||
102
MMDVMHost.cpp
102
MMDVMHost.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021,2023,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021,2023,2024,2025 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
|
||||||
|
|
@ -70,7 +70,7 @@ static void sigHandler(int signum)
|
||||||
const char* HEADER1 = "This software is for use on amateur radio networks only,";
|
const char* HEADER1 = "This software is for use on amateur radio networks only,";
|
||||||
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
|
||||||
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
const char* HEADER3 = "commercial networks is strictly prohibited.";
|
||||||
const char* HEADER4 = "Copyright(C) 2015-2024 by Jonathan Naylor, G4KLX and others";
|
const char* HEADER4 = "Copyright(C) 2015-2025 by Jonathan Naylor, G4KLX and others";
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
@ -497,7 +497,7 @@ int CMMDVMHost::run()
|
||||||
std::vector<std::string> whiteList = m_conf.getDStarWhiteList();
|
std::vector<std::string> whiteList = m_conf.getDStarWhiteList();
|
||||||
bool ackReply = m_conf.getDStarAckReply();
|
bool ackReply = m_conf.getDStarAckReply();
|
||||||
unsigned int ackTime = m_conf.getDStarAckTime();
|
unsigned int ackTime = m_conf.getDStarAckTime();
|
||||||
DSTAR_ACK_MESSAGE ackMessage = m_conf.getDStarAckMessage();
|
DSTAR_ACK ackMessage = m_conf.getDStarAckMessage();
|
||||||
bool errorReply = m_conf.getDStarErrorReply();
|
bool errorReply = m_conf.getDStarErrorReply();
|
||||||
bool remoteGateway = m_conf.getDStarRemoteGateway();
|
bool remoteGateway = m_conf.getDStarRemoteGateway();
|
||||||
m_dstarRFModeHang = m_conf.getDStarModeHang();
|
m_dstarRFModeHang = m_conf.getDStarModeHang();
|
||||||
|
|
@ -506,7 +506,7 @@ int CMMDVMHost::run()
|
||||||
LogInfo(" Module: %s", module.c_str());
|
LogInfo(" Module: %s", module.c_str());
|
||||||
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
||||||
LogInfo(" Ack Reply: %s", ackReply ? "yes" : "no");
|
LogInfo(" Ack Reply: %s", ackReply ? "yes" : "no");
|
||||||
LogInfo(" Ack message: %s", ackMessage == DSTAR_ACK_RSSI? "RSSI" : (ackMessage == DSTAR_ACK_SMETER ? "SMETER" : "BER"));
|
LogInfo(" Ack message: %s", ackMessage == DSTAR_ACK::RSSI? "RSSI" : (ackMessage == DSTAR_ACK::SMETER ? "SMETER" : "BER"));
|
||||||
LogInfo(" Ack Time: %ums", ackTime);
|
LogInfo(" Ack Time: %ums", ackTime);
|
||||||
LogInfo(" Error Reply: %s", errorReply ? "yes" : "no");
|
LogInfo(" Error Reply: %s", errorReply ? "yes" : "no");
|
||||||
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");
|
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");
|
||||||
|
|
@ -520,7 +520,7 @@ int CMMDVMHost::run()
|
||||||
m_dstar = new CDStarControl(m_callsign, module, selfOnly, ackReply, ackTime, ackMessage, errorReply, blackList, whiteList, m_dstarNetwork, m_display, m_timeout, m_duplex, remoteGateway, rssi);
|
m_dstar = new CDStarControl(m_callsign, module, selfOnly, ackReply, ackTime, ackMessage, errorReply, blackList, whiteList, m_dstarNetwork, m_display, m_timeout, m_duplex, remoteGateway, rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
DMR_BEACONS dmrBeacons = DMR_BEACONS_OFF;
|
DMR_BEACONS dmrBeacons = DMR_BEACONS::OFF;
|
||||||
CTimer dmrBeaconIntervalTimer(1000U);
|
CTimer dmrBeaconIntervalTimer(1000U);
|
||||||
CTimer dmrBeaconDurationTimer(1000U);
|
CTimer dmrBeaconDurationTimer(1000U);
|
||||||
|
|
||||||
|
|
@ -540,7 +540,7 @@ int CMMDVMHost::run()
|
||||||
unsigned int jitter = m_conf.getDMRNetworkJitter();
|
unsigned int jitter = m_conf.getDMRNetworkJitter();
|
||||||
m_dmrRFModeHang = m_conf.getDMRModeHang();
|
m_dmrRFModeHang = m_conf.getDMRModeHang();
|
||||||
dmrBeacons = m_conf.getDMRBeacons();
|
dmrBeacons = m_conf.getDMRBeacons();
|
||||||
DMR_OVCM_TYPES ovcm = m_conf.getDMROVCM();
|
DMR_OVCM ovcm = m_conf.getDMROVCM();
|
||||||
bool protect = m_conf.getDMRProtect();
|
bool protect = m_conf.getDMRProtect();
|
||||||
|
|
||||||
if (txHang > m_dmrRFModeHang)
|
if (txHang > m_dmrRFModeHang)
|
||||||
|
|
@ -574,22 +574,22 @@ int CMMDVMHost::run()
|
||||||
LogInfo(" Call Hang: %us", callHang);
|
LogInfo(" Call Hang: %us", callHang);
|
||||||
LogInfo(" TX Hang: %us", txHang);
|
LogInfo(" TX Hang: %us", txHang);
|
||||||
LogInfo(" Mode Hang: %us", m_dmrRFModeHang);
|
LogInfo(" Mode Hang: %us", m_dmrRFModeHang);
|
||||||
if (ovcm == DMR_OVCM_OFF)
|
if (ovcm == DMR_OVCM::OFF)
|
||||||
LogInfo(" OVCM: off");
|
LogInfo(" OVCM: off");
|
||||||
else if (ovcm == DMR_OVCM_RX_ON)
|
else if (ovcm == DMR_OVCM::RX_ON)
|
||||||
LogInfo(" OVCM: on(rx only)");
|
LogInfo(" OVCM: on(rx only)");
|
||||||
else if (ovcm == DMR_OVCM_TX_ON)
|
else if (ovcm == DMR_OVCM::TX_ON)
|
||||||
LogInfo(" OVCM: on(tx only)");
|
LogInfo(" OVCM: on(tx only)");
|
||||||
else if (ovcm == DMR_OVCM_ON)
|
else if (ovcm == DMR_OVCM::ON)
|
||||||
LogInfo(" OVCM: on");
|
LogInfo(" OVCM: on");
|
||||||
else if (ovcm == DMR_OVCM_FORCE_OFF)
|
else if (ovcm == DMR_OVCM::FORCE_OFF)
|
||||||
LogInfo(" OVCM: off (forced)");
|
LogInfo(" OVCM: off (forced)");
|
||||||
|
|
||||||
if (protect)
|
if (protect)
|
||||||
LogInfo(" Protect: yes");
|
LogInfo(" Protect: yes");
|
||||||
|
|
||||||
switch (dmrBeacons) {
|
switch (dmrBeacons) {
|
||||||
case DMR_BEACONS_NETWORK: {
|
case DMR_BEACONS::NETWORK: {
|
||||||
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
||||||
|
|
||||||
LogInfo(" DMR Roaming Beacons Type: network");
|
LogInfo(" DMR Roaming Beacons Type: network");
|
||||||
|
|
@ -598,7 +598,7 @@ int CMMDVMHost::run()
|
||||||
dmrBeaconDurationTimer.setTimeout(dmrBeaconDuration);
|
dmrBeaconDurationTimer.setTimeout(dmrBeaconDuration);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DMR_BEACONS_TIMED: {
|
case DMR_BEACONS::TIMED: {
|
||||||
unsigned int dmrBeaconInterval = m_conf.getDMRBeaconInterval();
|
unsigned int dmrBeaconInterval = m_conf.getDMRBeaconInterval();
|
||||||
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
||||||
|
|
||||||
|
|
@ -1253,7 +1253,7 @@ int CMMDVMHost::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (dmrBeacons) {
|
switch (dmrBeacons) {
|
||||||
case DMR_BEACONS_TIMED:
|
case DMR_BEACONS::TIMED:
|
||||||
dmrBeaconIntervalTimer.clock(ms);
|
dmrBeaconIntervalTimer.clock(ms);
|
||||||
if (dmrBeaconIntervalTimer.isRunning() && dmrBeaconIntervalTimer.hasExpired()) {
|
if (dmrBeaconIntervalTimer.isRunning() && dmrBeaconIntervalTimer.hasExpired()) {
|
||||||
if ((m_mode == MODE_IDLE || m_mode == MODE_DMR) && !m_modem->hasTX()) {
|
if ((m_mode == MODE_IDLE || m_mode == MODE_DMR) && !m_modem->hasTX()) {
|
||||||
|
|
@ -1266,7 +1266,7 @@ int CMMDVMHost::run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DMR_BEACONS_NETWORK:
|
case DMR_BEACONS::NETWORK:
|
||||||
if (m_dmrNetwork != NULL) {
|
if (m_dmrNetwork != NULL) {
|
||||||
bool beacon = m_dmrNetwork->wantsBeacon();
|
bool beacon = m_dmrNetwork->wantsBeacon();
|
||||||
if (beacon) {
|
if (beacon) {
|
||||||
|
|
@ -2544,131 +2544,131 @@ void CMMDVMHost::remoteControl()
|
||||||
|
|
||||||
REMOTE_COMMAND command = m_remoteControl->getCommand();
|
REMOTE_COMMAND command = m_remoteControl->getCommand();
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case RCD_MODE_IDLE:
|
case REMOTE_COMMAND::MODE_IDLE:
|
||||||
m_fixedMode = false;
|
m_fixedMode = false;
|
||||||
setMode(MODE_IDLE);
|
setMode(MODE_IDLE);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_LOCKOUT:
|
case REMOTE_COMMAND::MODE_LOCKOUT:
|
||||||
m_fixedMode = false;
|
m_fixedMode = false;
|
||||||
setMode(MODE_LOCKOUT);
|
setMode(MODE_LOCKOUT);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_DSTAR:
|
case REMOTE_COMMAND::MODE_DSTAR:
|
||||||
if (m_dstar != NULL)
|
if (m_dstar != NULL)
|
||||||
processModeCommand(MODE_DSTAR, m_dstarRFModeHang);
|
processModeCommand(MODE_DSTAR, m_dstarRFModeHang);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_DMR:
|
case REMOTE_COMMAND::MODE_DMR:
|
||||||
if (m_dmr != NULL)
|
if (m_dmr != NULL)
|
||||||
processModeCommand(MODE_DMR, m_dmrRFModeHang);
|
processModeCommand(MODE_DMR, m_dmrRFModeHang);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_YSF:
|
case REMOTE_COMMAND::MODE_YSF:
|
||||||
if (m_ysf != NULL)
|
if (m_ysf != NULL)
|
||||||
processModeCommand(MODE_YSF, m_ysfRFModeHang);
|
processModeCommand(MODE_YSF, m_ysfRFModeHang);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_P25:
|
case REMOTE_COMMAND::MODE_P25:
|
||||||
if (m_p25 != NULL)
|
if (m_p25 != NULL)
|
||||||
processModeCommand(MODE_P25, m_p25RFModeHang);
|
processModeCommand(MODE_P25, m_p25RFModeHang);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_NXDN:
|
case REMOTE_COMMAND::MODE_NXDN:
|
||||||
if (m_nxdn != NULL)
|
if (m_nxdn != NULL)
|
||||||
processModeCommand(MODE_NXDN, m_nxdnRFModeHang);
|
processModeCommand(MODE_NXDN, m_nxdnRFModeHang);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_M17:
|
case REMOTE_COMMAND::MODE_M17:
|
||||||
if (m_m17 != NULL)
|
if (m_m17 != NULL)
|
||||||
processModeCommand(MODE_M17, m_m17RFModeHang);
|
processModeCommand(MODE_M17, m_m17RFModeHang);
|
||||||
break;
|
break;
|
||||||
case RCD_MODE_FM:
|
case REMOTE_COMMAND::MODE_FM:
|
||||||
if (m_fmEnabled)
|
if (m_fmEnabled)
|
||||||
processModeCommand(MODE_FM, 0);
|
processModeCommand(MODE_FM, 0);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_DSTAR:
|
case REMOTE_COMMAND::ENABLE_DSTAR:
|
||||||
if (m_dstar != NULL && !m_dstarEnabled)
|
if (m_dstar != NULL && !m_dstarEnabled)
|
||||||
processEnableCommand(m_dstarEnabled, true);
|
processEnableCommand(m_dstarEnabled, true);
|
||||||
if (m_dstarNetwork != NULL)
|
if (m_dstarNetwork != NULL)
|
||||||
m_dstarNetwork->enable(true);
|
m_dstarNetwork->enable(true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_DMR:
|
case REMOTE_COMMAND::ENABLE_DMR:
|
||||||
if (m_dmr != NULL && !m_dmrEnabled)
|
if (m_dmr != NULL && !m_dmrEnabled)
|
||||||
processEnableCommand(m_dmrEnabled, true);
|
processEnableCommand(m_dmrEnabled, true);
|
||||||
if (m_dmrNetwork != NULL)
|
if (m_dmrNetwork != NULL)
|
||||||
m_dmrNetwork->enable(true);
|
m_dmrNetwork->enable(true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_YSF:
|
case REMOTE_COMMAND::ENABLE_YSF:
|
||||||
if (m_ysf != NULL && !m_ysfEnabled)
|
if (m_ysf != NULL && !m_ysfEnabled)
|
||||||
processEnableCommand(m_ysfEnabled, true);
|
processEnableCommand(m_ysfEnabled, true);
|
||||||
if (m_ysfNetwork != NULL)
|
if (m_ysfNetwork != NULL)
|
||||||
m_ysfNetwork->enable(true);
|
m_ysfNetwork->enable(true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_P25:
|
case REMOTE_COMMAND::ENABLE_P25:
|
||||||
if (m_p25 != NULL && !m_p25Enabled)
|
if (m_p25 != NULL && !m_p25Enabled)
|
||||||
processEnableCommand(m_p25Enabled, true);
|
processEnableCommand(m_p25Enabled, true);
|
||||||
if (m_p25Network != NULL)
|
if (m_p25Network != NULL)
|
||||||
m_p25Network->enable(true);
|
m_p25Network->enable(true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_NXDN:
|
case REMOTE_COMMAND::ENABLE_NXDN:
|
||||||
if (m_nxdn != NULL && !m_nxdnEnabled)
|
if (m_nxdn != NULL && !m_nxdnEnabled)
|
||||||
processEnableCommand(m_nxdnEnabled, true);
|
processEnableCommand(m_nxdnEnabled, true);
|
||||||
if (m_nxdnNetwork != NULL)
|
if (m_nxdnNetwork != NULL)
|
||||||
m_nxdnNetwork->enable(true);
|
m_nxdnNetwork->enable(true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_M17:
|
case REMOTE_COMMAND::ENABLE_M17:
|
||||||
if (m_m17 != NULL && !m_m17Enabled)
|
if (m_m17 != NULL && !m_m17Enabled)
|
||||||
processEnableCommand(m_m17Enabled, true);
|
processEnableCommand(m_m17Enabled, true);
|
||||||
if (m_m17Network != NULL)
|
if (m_m17Network != NULL)
|
||||||
m_m17Network->enable(true);
|
m_m17Network->enable(true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_FM:
|
case REMOTE_COMMAND::ENABLE_FM:
|
||||||
if (!m_fmEnabled)
|
if (!m_fmEnabled)
|
||||||
processEnableCommand(m_fmEnabled, true);
|
processEnableCommand(m_fmEnabled, true);
|
||||||
break;
|
break;
|
||||||
case RCD_ENABLE_AX25:
|
case REMOTE_COMMAND::ENABLE_AX25:
|
||||||
if (!m_ax25Enabled)
|
if (!m_ax25Enabled)
|
||||||
processEnableCommand(m_ax25Enabled, true);
|
processEnableCommand(m_ax25Enabled, true);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_DSTAR:
|
case REMOTE_COMMAND::DISABLE_DSTAR:
|
||||||
if (m_dstar != NULL && m_dstarEnabled)
|
if (m_dstar != NULL && m_dstarEnabled)
|
||||||
processEnableCommand(m_dstarEnabled, false);
|
processEnableCommand(m_dstarEnabled, false);
|
||||||
if (m_dstarNetwork != NULL)
|
if (m_dstarNetwork != NULL)
|
||||||
m_dstarNetwork->enable(false);
|
m_dstarNetwork->enable(false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_DMR:
|
case REMOTE_COMMAND::DISABLE_DMR:
|
||||||
if (m_dmr != NULL && m_dmrEnabled)
|
if (m_dmr != NULL && m_dmrEnabled)
|
||||||
processEnableCommand(m_dmrEnabled, false);
|
processEnableCommand(m_dmrEnabled, false);
|
||||||
if (m_dmrNetwork != NULL)
|
if (m_dmrNetwork != NULL)
|
||||||
m_dmrNetwork->enable(false);
|
m_dmrNetwork->enable(false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_YSF:
|
case REMOTE_COMMAND::DISABLE_YSF:
|
||||||
if (m_ysf != NULL && m_ysfEnabled)
|
if (m_ysf != NULL && m_ysfEnabled)
|
||||||
processEnableCommand(m_ysfEnabled, false);
|
processEnableCommand(m_ysfEnabled, false);
|
||||||
if (m_ysfNetwork != NULL)
|
if (m_ysfNetwork != NULL)
|
||||||
m_ysfNetwork->enable(false);
|
m_ysfNetwork->enable(false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_P25:
|
case REMOTE_COMMAND::DISABLE_P25:
|
||||||
if (m_p25 != NULL && m_p25Enabled)
|
if (m_p25 != NULL && m_p25Enabled)
|
||||||
processEnableCommand(m_p25Enabled, false);
|
processEnableCommand(m_p25Enabled, false);
|
||||||
if (m_p25Network != NULL)
|
if (m_p25Network != NULL)
|
||||||
m_p25Network->enable(false);
|
m_p25Network->enable(false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_NXDN:
|
case REMOTE_COMMAND::DISABLE_NXDN:
|
||||||
if (m_nxdn != NULL && m_nxdnEnabled)
|
if (m_nxdn != NULL && m_nxdnEnabled)
|
||||||
processEnableCommand(m_nxdnEnabled, false);
|
processEnableCommand(m_nxdnEnabled, false);
|
||||||
if (m_nxdnNetwork != NULL)
|
if (m_nxdnNetwork != NULL)
|
||||||
m_nxdnNetwork->enable(false);
|
m_nxdnNetwork->enable(false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_M17:
|
case REMOTE_COMMAND::DISABLE_M17:
|
||||||
if (m_m17 != NULL && m_m17Enabled)
|
if (m_m17 != NULL && m_m17Enabled)
|
||||||
processEnableCommand(m_m17Enabled, false);
|
processEnableCommand(m_m17Enabled, false);
|
||||||
if (m_m17Network != NULL)
|
if (m_m17Network != NULL)
|
||||||
m_m17Network->enable(false);
|
m_m17Network->enable(false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_FM:
|
case REMOTE_COMMAND::DISABLE_FM:
|
||||||
if (m_fmEnabled)
|
if (m_fmEnabled)
|
||||||
processEnableCommand(m_fmEnabled, false);
|
processEnableCommand(m_fmEnabled, false);
|
||||||
break;
|
break;
|
||||||
case RCD_DISABLE_AX25:
|
case REMOTE_COMMAND::DISABLE_AX25:
|
||||||
if (m_ax25Enabled == true)
|
if (m_ax25Enabled == true)
|
||||||
processEnableCommand(m_ax25Enabled, false);
|
processEnableCommand(m_ax25Enabled, false);
|
||||||
break;
|
break;
|
||||||
case RCD_PAGE:
|
case REMOTE_COMMAND::PAGE:
|
||||||
if (m_pocsag != NULL) {
|
if (m_pocsag != NULL) {
|
||||||
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
@ -2680,7 +2680,7 @@ void CMMDVMHost::remoteControl()
|
||||||
m_pocsag->sendPage(ric, text);
|
m_pocsag->sendPage(ric, text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RCD_PAGE_BCD:
|
case REMOTE_COMMAND::PAGE_BCD:
|
||||||
if (m_pocsag != NULL) {
|
if (m_pocsag != NULL) {
|
||||||
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
@ -2692,13 +2692,13 @@ void CMMDVMHost::remoteControl()
|
||||||
m_pocsag->sendPageBCD(ric, text);
|
m_pocsag->sendPageBCD(ric, text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RCD_PAGE_A1:
|
case REMOTE_COMMAND::PAGE_A1:
|
||||||
if (m_pocsag != NULL) {
|
if (m_pocsag != NULL) {
|
||||||
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
||||||
m_pocsag->sendPageAlert1(ric);
|
m_pocsag->sendPageAlert1(ric);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RCD_PAGE_A2:
|
case REMOTE_COMMAND::PAGE_A2:
|
||||||
if (m_pocsag != NULL) {
|
if (m_pocsag != NULL) {
|
||||||
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
unsigned int ric = m_remoteControl->getArgUInt(0U);
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
@ -2710,7 +2710,7 @@ void CMMDVMHost::remoteControl()
|
||||||
m_pocsag->sendPageAlert2(ric, text);
|
m_pocsag->sendPageAlert2(ric, text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RCD_CW:
|
case REMOTE_COMMAND::CW:
|
||||||
setMode(MODE_IDLE); // Force the modem to go idle so that we can send the CW text.
|
setMode(MODE_IDLE); // Force the modem to go idle so that we can send the CW text.
|
||||||
if (!m_modem->hasTX()) {
|
if (!m_modem->hasTX()) {
|
||||||
std::string cwtext;
|
std::string cwtext;
|
||||||
|
|
@ -2723,7 +2723,7 @@ void CMMDVMHost::remoteControl()
|
||||||
m_modem->sendCWId(cwtext);
|
m_modem->sendCWId(cwtext);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RCD_RELOAD:
|
case REMOTE_COMMAND::RELOAD:
|
||||||
m_reload = true;
|
m_reload = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2785,11 +2785,11 @@ void CMMDVMHost::buildNetworkHostsString(std::string &str)
|
||||||
|
|
||||||
m_dstarNetwork->getStatus(status, &ref[0]);
|
m_dstarNetwork->getStatus(status, &ref[0]);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case LINK_STATUS::LS_LINKED_LOOPBACK:
|
case LINK_STATUS::LINKED_LOOPBACK:
|
||||||
case LINK_STATUS::LS_LINKED_DEXTRA:
|
case LINK_STATUS::LINKED_DEXTRA:
|
||||||
case LINK_STATUS::LS_LINKED_DPLUS:
|
case LINK_STATUS::LINKED_DPLUS:
|
||||||
case LINK_STATUS::LS_LINKED_DCS:
|
case LINK_STATUS::LINKED_DCS:
|
||||||
case LINK_STATUS::LS_LINKED_CCS:
|
case LINK_STATUS::LINKED_CCS:
|
||||||
dstarReflector = std::string((char *)ref);
|
dstarReflector = std::string((char *)ref);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
136
Modem.cpp
136
Modem.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2018,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2011-2018,2020,2021,2025 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
|
||||||
|
|
@ -169,7 +169,7 @@ m_port(NULL),
|
||||||
m_buffer(NULL),
|
m_buffer(NULL),
|
||||||
m_length(0U),
|
m_length(0U),
|
||||||
m_offset(0U),
|
m_offset(0U),
|
||||||
m_state(SS_START),
|
m_state(SERIAL_STATE::START),
|
||||||
m_type(0U),
|
m_type(0U),
|
||||||
m_rxDStarData(1000U, "Modem RX D-Star"),
|
m_rxDStarData(1000U, "Modem RX D-Star"),
|
||||||
m_txDStarData(1000U, "Modem TX D-Star"),
|
m_txDStarData(1000U, "Modem TX D-Star"),
|
||||||
|
|
@ -213,7 +213,7 @@ m_cd(false),
|
||||||
m_lockout(false),
|
m_lockout(false),
|
||||||
m_error(false),
|
m_error(false),
|
||||||
m_mode(MODE_IDLE),
|
m_mode(MODE_IDLE),
|
||||||
m_hwType(HWT_UNKNOWN),
|
m_hwType(HW_TYPE::UNKNOWN),
|
||||||
m_ax25RXTwist(0),
|
m_ax25RXTwist(0),
|
||||||
m_ax25TXDelay(300U),
|
m_ax25TXDelay(300U),
|
||||||
m_ax25SlotTime(30U),
|
m_ax25SlotTime(30U),
|
||||||
|
|
@ -455,12 +455,12 @@ void CModem::clock(unsigned int ms)
|
||||||
|
|
||||||
RESP_TYPE_MMDVM type = getResponse();
|
RESP_TYPE_MMDVM type = getResponse();
|
||||||
|
|
||||||
if (type == RTM_TIMEOUT) {
|
if (type == RESP_TYPE_MMDVM::TIMEOUT) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
} else if (type == RTM_ERROR) {
|
} else if (type == RESP_TYPE_MMDVM::ERR) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
} else {
|
} else {
|
||||||
// type == RTM_OK
|
// type == OK
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case MMDVM_DSTAR_HEADER: {
|
case MMDVM_DSTAR_HEADER: {
|
||||||
if (m_trace)
|
if (m_trace)
|
||||||
|
|
@ -1996,31 +1996,31 @@ bool CModem::readVersion()
|
||||||
for (unsigned int count = 0U; count < MAX_RESPONSES; count++) {
|
for (unsigned int count = 0U; count < MAX_RESPONSES; count++) {
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
RESP_TYPE_MMDVM resp = getResponse();
|
RESP_TYPE_MMDVM resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_GET_VERSION) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_GET_VERSION)) {
|
||||||
if (::memcmp(m_buffer + 4U, "MMDVM ", 6U) == 0)
|
if (::memcmp(m_buffer + 4U, "MMDVM ", 6U) == 0)
|
||||||
m_hwType = HWT_MMDVM;
|
m_hwType = HW_TYPE::MMDVM;
|
||||||
else if (::memcmp(m_buffer + 23U, "MMDVM ", 6U) == 0)
|
else if (::memcmp(m_buffer + 23U, "MMDVM ", 6U) == 0)
|
||||||
m_hwType = HWT_MMDVM;
|
m_hwType = HW_TYPE::MMDVM;
|
||||||
else if (::memcmp(m_buffer + 4U, "DVMEGA", 6U) == 0)
|
else if (::memcmp(m_buffer + 4U, "DVMEGA", 6U) == 0)
|
||||||
m_hwType = HWT_DVMEGA;
|
m_hwType = HW_TYPE::DVMEGA;
|
||||||
else if (::memcmp(m_buffer + 4U, "ZUMspot", 7U) == 0)
|
else if (::memcmp(m_buffer + 4U, "ZUMspot", 7U) == 0)
|
||||||
m_hwType = HWT_MMDVM_ZUMSPOT;
|
m_hwType = HW_TYPE::MMDVM_ZUMSPOT;
|
||||||
else if (::memcmp(m_buffer + 4U, "MMDVM_HS_Hat", 12U) == 0)
|
else if (::memcmp(m_buffer + 4U, "MMDVM_HS_Hat", 12U) == 0)
|
||||||
m_hwType = HWT_MMDVM_HS_HAT;
|
m_hwType = HW_TYPE::MMDVM_HS_HAT;
|
||||||
else if (::memcmp(m_buffer + 4U, "MMDVM_HS_Dual_Hat", 17U) == 0)
|
else if (::memcmp(m_buffer + 4U, "MMDVM_HS_Dual_Hat", 17U) == 0)
|
||||||
m_hwType = HWT_MMDVM_HS_DUAL_HAT;
|
m_hwType = HW_TYPE::MMDVM_HS_DUAL_HAT;
|
||||||
else if (::memcmp(m_buffer + 4U, "Nano_hotSPOT", 12U) == 0)
|
else if (::memcmp(m_buffer + 4U, "Nano_hotSPOT", 12U) == 0)
|
||||||
m_hwType = HWT_NANO_HOTSPOT;
|
m_hwType = HW_TYPE::NANO_HOTSPOT;
|
||||||
else if (::memcmp(m_buffer + 4U, "Nano_DV", 7U) == 0)
|
else if (::memcmp(m_buffer + 4U, "Nano_DV", 7U) == 0)
|
||||||
m_hwType = HWT_NANO_DV;
|
m_hwType = HW_TYPE::NANO_DV;
|
||||||
else if (::memcmp(m_buffer + 4U, "D2RG_MMDVM_HS", 13U) == 0)
|
else if (::memcmp(m_buffer + 4U, "D2RG_MMDVM_HS", 13U) == 0)
|
||||||
m_hwType = HWT_D2RG_MMDVM_HS;
|
m_hwType = HW_TYPE::D2RG_MMDVM_HS;
|
||||||
else if (::memcmp(m_buffer + 4U, "MMDVM_HS-", 9U) == 0)
|
else if (::memcmp(m_buffer + 4U, "MMDVM_HS-", 9U) == 0)
|
||||||
m_hwType = HWT_MMDVM_HS;
|
m_hwType = HW_TYPE::MMDVM_HS;
|
||||||
else if (::memcmp(m_buffer + 4U, "OpenGD77_HS", 11U) == 0)
|
else if (::memcmp(m_buffer + 4U, "OpenGD77_HS", 11U) == 0)
|
||||||
m_hwType = HWT_OPENGD77_HS;
|
m_hwType = HW_TYPE::OPENGD77_HS;
|
||||||
else if (::memcmp(m_buffer + 4U, "SkyBridge", 9U) == 0)
|
else if (::memcmp(m_buffer + 4U, "SkyBridge", 9U) == 0)
|
||||||
m_hwType = HWT_SKYBRIDGE;
|
m_hwType = HW_TYPE::SKYBRIDGE;
|
||||||
|
|
||||||
m_protocolVersion = m_buffer[3U];
|
m_protocolVersion = m_buffer[3U];
|
||||||
|
|
||||||
|
|
@ -2210,18 +2210,18 @@ bool CModem::setConfig1()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_CONFIG command");
|
LogError("The MMDVM is not responding to the SET_CONFIG command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_CONFIG command from the modem");
|
LogError("Received a NAK to the SET_CONFIG command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2336,18 +2336,18 @@ bool CModem::setConfig2()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_CONFIG command");
|
LogError("The MMDVM is not responding to the SET_CONFIG command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_CONFIG command from the modem");
|
LogError("Received a NAK to the SET_CONFIG command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2368,7 +2368,7 @@ bool CModem::setFrequency()
|
||||||
if (m_pocsagEnabled)
|
if (m_pocsagEnabled)
|
||||||
pocsagFrequency = m_pocsagFrequency;
|
pocsagFrequency = m_pocsagFrequency;
|
||||||
|
|
||||||
if (m_hwType == HWT_DVMEGA)
|
if (m_hwType == HW_TYPE::DVMEGA)
|
||||||
len = 12U;
|
len = 12U;
|
||||||
else {
|
else {
|
||||||
buffer[12U] = (unsigned char)(m_rfLevel * 2.55F + 0.5F);
|
buffer[12U] = (unsigned char)(m_rfLevel * 2.55F + 0.5F);
|
||||||
|
|
@ -2411,18 +2411,18 @@ bool CModem::setFrequency()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_FREQ command");
|
LogError("The MMDVM is not responding to the SET_FREQ command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_FREQ command from the modem");
|
LogError("Received a NAK to the SET_FREQ command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2434,90 +2434,90 @@ RESP_TYPE_MMDVM CModem::getResponse()
|
||||||
{
|
{
|
||||||
assert(m_port != NULL);
|
assert(m_port != NULL);
|
||||||
|
|
||||||
if (m_state == SS_START) {
|
if (m_state == SERIAL_STATE::START) {
|
||||||
// Get the start of the frame or nothing at all
|
// Get the start of the frame or nothing at all
|
||||||
int ret = m_port->read(m_buffer + 0U, 1U);
|
int ret = m_port->read(m_buffer + 0U, 1U);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LogError("Error when reading from the modem");
|
LogError("Error when reading from the modem");
|
||||||
return RTM_ERROR;
|
return RESP_TYPE_MMDVM::ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return RTM_TIMEOUT;
|
return RESP_TYPE_MMDVM::TIMEOUT;
|
||||||
|
|
||||||
if (m_buffer[0U] != MMDVM_FRAME_START)
|
if (m_buffer[0U] != MMDVM_FRAME_START)
|
||||||
return RTM_TIMEOUT;
|
return RESP_TYPE_MMDVM::TIMEOUT;
|
||||||
|
|
||||||
m_state = SS_LENGTH1;
|
m_state = SERIAL_STATE::LENGTH1;
|
||||||
m_length = 1U;
|
m_length = 1U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == SS_LENGTH1) {
|
if (m_state == SERIAL_STATE::LENGTH1) {
|
||||||
// Get the length of the frame, 1/2
|
// Get the length of the frame, 1/2
|
||||||
int ret = m_port->read(m_buffer + 1U, 1U);
|
int ret = m_port->read(m_buffer + 1U, 1U);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LogError("Error when reading from the modem");
|
LogError("Error when reading from the modem");
|
||||||
m_state = SS_START;
|
m_state = SERIAL_STATE::START;
|
||||||
return RTM_ERROR;
|
return RESP_TYPE_MMDVM::ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return RTM_TIMEOUT;
|
return RESP_TYPE_MMDVM::TIMEOUT;
|
||||||
|
|
||||||
m_length = m_buffer[1U];
|
m_length = m_buffer[1U];
|
||||||
m_offset = 2U;
|
m_offset = 2U;
|
||||||
|
|
||||||
if (m_length == 0U)
|
if (m_length == 0U)
|
||||||
m_state = SS_LENGTH2;
|
m_state = SERIAL_STATE::LENGTH2;
|
||||||
else
|
else
|
||||||
m_state = SS_TYPE;
|
m_state = SERIAL_STATE::TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == SS_LENGTH2) {
|
if (m_state == SERIAL_STATE::LENGTH2) {
|
||||||
// Get the length of the frane, 2/2
|
// Get the length of the frane, 2/2
|
||||||
int ret = m_port->read(m_buffer + 2U, 1U);
|
int ret = m_port->read(m_buffer + 2U, 1U);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LogError("Error when reading from the modem");
|
LogError("Error when reading from the modem");
|
||||||
m_state = SS_START;
|
m_state = SERIAL_STATE::START;
|
||||||
return RTM_ERROR;
|
return RESP_TYPE_MMDVM::ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return RTM_TIMEOUT;
|
return RESP_TYPE_MMDVM::TIMEOUT;
|
||||||
|
|
||||||
m_length = m_buffer[2U] + 255U;
|
m_length = m_buffer[2U] + 255U;
|
||||||
m_offset = 3U;
|
m_offset = 3U;
|
||||||
m_state = SS_TYPE;
|
m_state = SERIAL_STATE::TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == SS_TYPE) {
|
if (m_state == SERIAL_STATE::TYPE) {
|
||||||
// Get the frame type
|
// Get the frame type
|
||||||
int ret = m_port->read(&m_type, 1U);
|
int ret = m_port->read(&m_type, 1U);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LogError("Error when reading from the modem");
|
LogError("Error when reading from the modem");
|
||||||
m_state = SS_START;
|
m_state = SERIAL_STATE::START;
|
||||||
return RTM_ERROR;
|
return RESP_TYPE_MMDVM::ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return RTM_TIMEOUT;
|
return RESP_TYPE_MMDVM::TIMEOUT;
|
||||||
|
|
||||||
m_buffer[m_offset++] = m_type;
|
m_buffer[m_offset++] = m_type;
|
||||||
|
|
||||||
m_state = SS_DATA;
|
m_state = SERIAL_STATE::DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == SS_DATA) {
|
if (m_state == SERIAL_STATE::DATA) {
|
||||||
while (m_offset < m_length) {
|
while (m_offset < m_length) {
|
||||||
int ret = m_port->read(m_buffer + m_offset, m_length - m_offset);
|
int ret = m_port->read(m_buffer + m_offset, m_length - m_offset);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LogError("Error when reading from the modem");
|
LogError("Error when reading from the modem");
|
||||||
m_state = SS_START;
|
m_state = SERIAL_STATE::START;
|
||||||
return RTM_ERROR;
|
return RESP_TYPE_MMDVM::ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return RTM_TIMEOUT;
|
return RESP_TYPE_MMDVM::TIMEOUT;
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
m_offset += ret;
|
m_offset += ret;
|
||||||
|
|
@ -2527,9 +2527,9 @@ RESP_TYPE_MMDVM CModem::getResponse()
|
||||||
// CUtils::dump(1U, "Received", m_buffer, m_length);
|
// CUtils::dump(1U, "Received", m_buffer, m_length);
|
||||||
|
|
||||||
m_offset = m_length > 255U ? 4U : 3U;
|
m_offset = m_length > 255U ? 4U : 3U;
|
||||||
m_state = SS_START;
|
m_state = SERIAL_STATE::START;
|
||||||
|
|
||||||
return RTM_OK;
|
return RESP_TYPE_MMDVM::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HW_TYPE CModem::getHWType() const
|
HW_TYPE CModem::getHWType() const
|
||||||
|
|
@ -2746,18 +2746,18 @@ bool CModem::setFMCallsignParams()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_FM_PARAMS1 command");
|
LogError("The MMDVM is not responding to the SET_FM_PARAMS1 command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_FM_PARAMS1 command from the modem");
|
LogError("Received a NAK to the SET_FM_PARAMS1 command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2798,18 +2798,18 @@ bool CModem::setFMAckParams()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_FM_PARAMS2 command");
|
LogError("The MMDVM is not responding to the SET_FM_PARAMS2 command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_FM_PARAMS2 command from the modem");
|
LogError("Received a NAK to the SET_FM_PARAMS2 command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2867,18 +2867,18 @@ bool CModem::setFMMiscParams()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_FM_PARAMS3 command");
|
LogError("The MMDVM is not responding to the SET_FM_PARAMS3 command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_FM_PARAMS3 command from the modem");
|
LogError("Received a NAK to the SET_FM_PARAMS3 command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2918,18 +2918,18 @@ bool CModem::setFMExtParams()
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
|
|
||||||
resp = getResponse();
|
resp = getResponse();
|
||||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= MAX_RESPONSES) {
|
if (count >= MAX_RESPONSES) {
|
||||||
LogError("The MMDVM is not responding to the SET_FM_PARAMS4 command");
|
LogError("The MMDVM is not responding to the SET_FM_PARAMS4 command");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK);
|
} while ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] != MMDVM_ACK) && (m_buffer[2U] != MMDVM_NAK));
|
||||||
|
|
||||||
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
// CUtils::dump(1U, "Response", m_buffer, m_length);
|
||||||
|
|
||||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_NAK) {
|
if ((resp == RESP_TYPE_MMDVM::OK) && (m_buffer[2U] == MMDVM_NAK)) {
|
||||||
LogError("Received a NAK to the SET_FM_PARAMS4 command from the modem");
|
LogError("Received a NAK to the SET_FM_PARAMS4 command from the modem");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
Modem.h
22
Modem.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2018,2020,2021 by Jonathan Naylor G4KLX
|
* Copyright (C) 2011-2018,2020,2021,2025 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
|
||||||
|
|
@ -26,18 +26,18 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum RESP_TYPE_MMDVM {
|
enum class RESP_TYPE_MMDVM {
|
||||||
RTM_OK,
|
OK,
|
||||||
RTM_TIMEOUT,
|
TIMEOUT,
|
||||||
RTM_ERROR
|
ERR
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SERIAL_STATE {
|
enum class SERIAL_STATE {
|
||||||
SS_START,
|
START,
|
||||||
SS_LENGTH1,
|
LENGTH1,
|
||||||
SS_LENGTH2,
|
LENGTH2,
|
||||||
SS_TYPE,
|
TYPE,
|
||||||
SS_DATA
|
DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
class CModem {
|
class CModem {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015-2021,2025 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
|
||||||
|
|
@ -49,8 +49,8 @@ m_duplex(duplex),
|
||||||
m_remoteGateway(remoteGateway),
|
m_remoteGateway(remoteGateway),
|
||||||
m_lookup(lookup),
|
m_lookup(lookup),
|
||||||
m_queue(5000U, "NXDN Control"),
|
m_queue(5000U, "NXDN Control"),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RPT_RF_STATE::LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RPT_NET_STATE::IDLE),
|
||||||
m_rfTimeoutTimer(1000U, timeout),
|
m_rfTimeoutTimer(1000U, timeout),
|
||||||
m_netTimeoutTimer(1000U, timeout),
|
m_netTimeoutTimer(1000U, timeout),
|
||||||
m_packetTimer(1000U, 0U, 200U),
|
m_packetTimer(1000U, 0U, 200U),
|
||||||
|
|
@ -92,7 +92,7 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::AUDIO)) {
|
||||||
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||||
bool grp = m_rfLayer3.getIsGroup();
|
bool grp = m_rfLayer3.getIsGroup();
|
||||||
std::string source = m_lookup->find(m_rfLayer3.getSourceUnitId());
|
std::string source = m_lookup->find(m_rfLayer3.getSourceUnitId());
|
||||||
|
|
@ -105,13 +105,13 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_DATA) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::DATA)) {
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST) {
|
if (type == TAG_LOST) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfMask = 0x00U;
|
m_rfMask = 0x00U;
|
||||||
m_rfLayer3.reset();
|
m_rfLayer3.reset();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -179,7 +179,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
unsigned char ran = sacch.getRAN();
|
unsigned char ran = sacch.getRAN();
|
||||||
if (ran != m_ran && ran != 0U)
|
if (ran != m_ran && ran != 0U)
|
||||||
return false;
|
return false;
|
||||||
} else if (m_rfState == RS_RF_LISTENING) {
|
} else if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,17 +203,17 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
|
|
||||||
unsigned char type = layer3.getMessageType();
|
unsigned char type = layer3.getMessageType();
|
||||||
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||||
if (m_rfState != RS_RF_AUDIO) {
|
if (m_rfState != RPT_RF_STATE::AUDIO) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfMask = 0x00U;
|
m_rfMask = 0x00U;
|
||||||
m_rfLayer3.reset();
|
m_rfLayer3.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (type == NXDN_MESSAGE_TYPE_VCALL) {
|
} else if (type == NXDN_MESSAGE_TYPE_VCALL) {
|
||||||
if (m_rfState == RS_RF_LISTENING && m_selfOnly) {
|
if ((m_rfState == RPT_RF_STATE::LISTENING) && m_selfOnly) {
|
||||||
unsigned short srcId = layer3.getSourceUnitId();
|
unsigned short srcId = layer3.getSourceUnitId();
|
||||||
if (srcId != m_id) {
|
if (srcId != m_id) {
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -254,7 +254,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
|
|
||||||
scrambler(data + 2U);
|
scrambler(data + 2U);
|
||||||
|
|
||||||
writeNetwork(netData, data[0U] == TAG_EOT ? NNMT_VOICE_TRAILER : NNMT_VOICE_HEADER);
|
writeNetwork(netData, data[0U] == TAG_EOT ? NXDN_NETWORK_MESSAGE_TYPE::VOICE_TRAILER : NXDN_NETWORK_MESSAGE_TYPE::VOICE_HEADER);
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
|
|
@ -278,7 +278,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 1U;
|
m_rfBits = 1U;
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
m_aveRSSI = m_rssi;
|
m_aveRSSI = m_rssi;
|
||||||
|
|
@ -297,7 +297,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
CNXDNFACCH1 facch;
|
CNXDNFACCH1 facch;
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
switch (option) {
|
switch (option) {
|
||||||
|
|
@ -374,7 +374,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
|
|
||||||
if (m_selfOnly) {
|
if (m_selfOnly) {
|
||||||
if (srcId != m_id) {
|
if (srcId != m_id) {
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +383,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 1U;
|
m_rfBits = 1U;
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
|
|
@ -396,7 +396,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
LogMessage("NXDN, received RF late entry from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
LogMessage("NXDN, received RF late entry from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||||
m_display->writeNXDN(source.c_str(), grp, dstId, "R");
|
m_display->writeNXDN(source.c_str(), grp, dstId, "R");
|
||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
// Create a dummy start message
|
// Create a dummy start message
|
||||||
unsigned char start[NXDN_FRAME_LENGTH_BYTES + 2U];
|
unsigned char start[NXDN_FRAME_LENGTH_BYTES + 2U];
|
||||||
|
|
@ -438,7 +438,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
|
|
||||||
scrambler(start + 2U);
|
scrambler(start + 2U);
|
||||||
|
|
||||||
writeNetwork(netData, NNMT_VOICE_HEADER);
|
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::VOICE_HEADER);
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
writeFile(start + 2U);
|
writeFile(start + 2U);
|
||||||
|
|
@ -448,7 +448,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
// Regenerate the sync
|
// Regenerate the sync
|
||||||
CSync::addNXDNSync(data + 2U);
|
CSync::addNXDNSync(data + 2U);
|
||||||
|
|
||||||
|
|
@ -544,7 +544,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
||||||
|
|
||||||
scrambler(data + 2U);
|
scrambler(data + 2U);
|
||||||
|
|
||||||
writeNetwork(netData, NNMT_VOICE_BODY);
|
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::VOICE_BODY);
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
|
|
@ -565,7 +565,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
{
|
{
|
||||||
CNXDNUDCH udch;
|
CNXDNUDCH udch;
|
||||||
bool validUDCH = udch.decode(data + 2U);
|
bool validUDCH = udch.decode(data + 2U);
|
||||||
if (m_rfState == RS_RF_LISTENING && !validUDCH)
|
if ((m_rfState == RPT_RF_STATE::LISTENING) && !validUDCH)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (validUDCH) {
|
if (validUDCH) {
|
||||||
|
|
@ -584,7 +584,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
CNXDNLayer3 layer3;
|
CNXDNLayer3 layer3;
|
||||||
layer3.decode(buffer, 184U);
|
layer3.decode(buffer, 184U);
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
unsigned char type = layer3.getMessageType();
|
unsigned char type = layer3.getMessageType();
|
||||||
if (type != NXDN_MESSAGE_TYPE_DCALL_HDR)
|
if (type != NXDN_MESSAGE_TYPE_DCALL_HDR)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -610,14 +610,14 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
m_rfLayer3 = layer3;
|
m_rfLayer3 = layer3;
|
||||||
m_rfFrames = 0U;
|
m_rfFrames = 0U;
|
||||||
|
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
|
|
||||||
#if defined(DUMP_NXDN)
|
#if defined(DUMP_NXDN)
|
||||||
openFile();
|
openFile();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState != RS_RF_DATA)
|
if (m_rfState != RPT_RF_STATE::DATA)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CSync::addNXDNSync(data + 2U);
|
CSync::addNXDNSync(data + 2U);
|
||||||
|
|
@ -651,13 +651,13 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NXDN_MESSAGE_TYPE_DCALL_HDR:
|
case NXDN_MESSAGE_TYPE_DCALL_HDR:
|
||||||
writeNetwork(netData, NNMT_DATA_HEADER);
|
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::DATA_HEADER);
|
||||||
break;
|
break;
|
||||||
case NXDN_MESSAGE_TYPE_TX_REL:
|
case NXDN_MESSAGE_TYPE_TX_REL:
|
||||||
writeNetwork(netData, NNMT_DATA_TRAILER);
|
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::DATA_TRAILER);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
writeNetwork(netData, NNMT_DATA_BODY);
|
writeNetwork(netData, NXDN_NETWORK_MESSAGE_TYPE::DATA_BODY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -699,14 +699,14 @@ unsigned int CNXDNControl::readModem(unsigned char* data)
|
||||||
|
|
||||||
void CNXDNControl::writeEndRF()
|
void CNXDNControl::writeEndRF()
|
||||||
{
|
{
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfMask = 0x00U;
|
m_rfMask = 0x00U;
|
||||||
m_rfLayer3.reset();
|
m_rfLayer3.reset();
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_display->clearNXDN();
|
m_display->clearNXDN();
|
||||||
|
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
|
|
@ -720,7 +720,7 @@ void CNXDNControl::writeEndRF()
|
||||||
|
|
||||||
void CNXDNControl::writeEndNet()
|
void CNXDNControl::writeEndNet()
|
||||||
{
|
{
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_netMask = 0x00U;
|
m_netMask = 0x00U;
|
||||||
m_netLayer3.reset();
|
m_netLayer3.reset();
|
||||||
|
|
@ -745,7 +745,7 @@ void CNXDNControl::writeNetwork()
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
if ((m_rfState != RPT_RF_STATE::LISTENING) && (m_netState == RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
@ -766,7 +766,7 @@ void CNXDNControl::writeNetwork()
|
||||||
layer3.setData(netData + 2U, 23U);
|
layer3.setData(netData + 2U, 23U);
|
||||||
unsigned char type = layer3.getMessageType();
|
unsigned char type = layer3.getMessageType();
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
if (type == NXDN_MESSAGE_TYPE_DCALL_HDR) {
|
if (type == NXDN_MESSAGE_TYPE_DCALL_HDR) {
|
||||||
unsigned short srcId = layer3.getSourceUnitId();
|
unsigned short srcId = layer3.getSourceUnitId();
|
||||||
unsigned short dstId = layer3.getDestinationGroupId();
|
unsigned short dstId = layer3.getDestinationGroupId();
|
||||||
|
|
@ -778,13 +778,13 @@ void CNXDNControl::writeNetwork()
|
||||||
m_display->writeNXDN(source.c_str(), grp, dstId, "N");
|
m_display->writeNXDN(source.c_str(), grp, dstId, "N");
|
||||||
LogMessage("NXDN, received network data header from %s to %s%u, %u blocks", source.c_str(), grp ? "TG " : "", dstId, frames);
|
LogMessage("NXDN, received network data header from %s to %s%u, %u blocks", source.c_str(), grp ? "TG " : "", dstId, frames);
|
||||||
|
|
||||||
m_netState = RS_NET_DATA;
|
m_netState = RPT_NET_STATE::DATA;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_netState == RS_NET_DATA) {
|
if (m_netState == RPT_NET_STATE::DATA) {
|
||||||
data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA;
|
data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
|
|
@ -810,9 +810,9 @@ void CNXDNControl::writeNetwork()
|
||||||
m_netLayer3.setData(netData + 5U + 0U, 10U);
|
m_netLayer3.setData(netData + 5U + 0U, 10U);
|
||||||
|
|
||||||
unsigned char type = m_netLayer3.getMessageType();
|
unsigned char type = m_netLayer3.getMessageType();
|
||||||
if (type == NXDN_MESSAGE_TYPE_TX_REL && m_netState == RS_NET_IDLE)
|
if ((type == NXDN_MESSAGE_TYPE_TX_REL) && (m_netState == RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
if (type == NXDN_MESSAGE_TYPE_VCALL && m_netState != RS_NET_IDLE)
|
if ((type == NXDN_MESSAGE_TYPE_VCALL) && (m_netState != RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CNXDNSACCH sacch;
|
CNXDNSACCH sacch;
|
||||||
|
|
@ -849,14 +849,14 @@ void CNXDNControl::writeNetwork()
|
||||||
m_netTimeoutTimer.start();
|
m_netTimeoutTimer.start();
|
||||||
m_packetTimer.start();
|
m_packetTimer.start();
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
m_netFrames = 1U;
|
m_netFrames = 1U;
|
||||||
} else {
|
} else {
|
||||||
CUtils::dump(2U, "NXDN, interesting non superblock network frame", netData, 33U);
|
CUtils::dump(2U, "NXDN, interesting non superblock network frame", netData, 33U);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
unsigned char structure = (netData[1U] >> 6) & 0x03U;
|
unsigned char structure = (netData[1U] >> 6) & 0x03U;
|
||||||
switch (structure) {
|
switch (structure) {
|
||||||
case NXDN_SR_1_4:
|
case NXDN_SR_1_4:
|
||||||
|
|
@ -901,7 +901,7 @@ void CNXDNControl::writeNetwork()
|
||||||
m_netTimeoutTimer.start();
|
m_netTimeoutTimer.start();
|
||||||
m_packetTimer.start();
|
m_packetTimer.start();
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
m_netFrames = 1U;
|
m_netFrames = 1U;
|
||||||
|
|
||||||
// Create a dummy start message
|
// Create a dummy start message
|
||||||
|
|
@ -992,7 +992,7 @@ void CNXDNControl::clock(unsigned int ms)
|
||||||
m_rfTimeoutTimer.clock(ms);
|
m_rfTimeoutTimer.clock(ms);
|
||||||
m_netTimeoutTimer.clock(ms);
|
m_netTimeoutTimer.clock(ms);
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
|
|
@ -1006,7 +1006,7 @@ void CNXDNControl::writeQueueRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
|
@ -1108,7 +1108,7 @@ void CNXDNControl::closeFile()
|
||||||
|
|
||||||
bool CNXDNControl::isBusy() const
|
bool CNXDNControl::isBusy() const
|
||||||
{
|
{
|
||||||
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
|
return (m_rfState != RPT_RF_STATE::LISTENING) || (m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNXDNControl::enable(bool enabled)
|
void CNXDNControl::enable(bool enabled)
|
||||||
|
|
@ -1117,7 +1117,7 @@ void CNXDNControl::enable(bool enabled)
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
|
|
||||||
// Reset the RF section
|
// Reset the RF section
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfMask = 0x00U;
|
m_rfMask = 0x00U;
|
||||||
m_rfLayer3.reset();
|
m_rfLayer3.reset();
|
||||||
|
|
@ -1125,7 +1125,7 @@ void CNXDNControl::enable(bool enabled)
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
// Reset the networking section
|
// Reset the networking section
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_netMask = 0x00U;
|
m_netMask = 0x00U;
|
||||||
m_netLayer3.reset();
|
m_netLayer3.reset();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2018,2025 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
|
||||||
|
|
@ -50,7 +50,7 @@ const unsigned char NXDN_LICH_RFCT_RTCH_C = 3U;
|
||||||
const unsigned char NXDN_LICH_USC_SACCH_NS = 0U;
|
const unsigned char NXDN_LICH_USC_SACCH_NS = 0U;
|
||||||
const unsigned char NXDN_LICH_USC_UDCH = 1U;
|
const unsigned char NXDN_LICH_USC_UDCH = 1U;
|
||||||
const unsigned char NXDN_LICH_USC_SACCH_SS = 2U;
|
const unsigned char NXDN_LICH_USC_SACCH_SS = 2U;
|
||||||
const unsigned char NXDN_LICH_USC_SACCH_SS_IDLE = 3U;
|
const unsigned char NXDN_LICH_USC_SACCH_IDLE = 3U;
|
||||||
|
|
||||||
const unsigned char NXDN_LICH_STEAL_NONE = 3U;
|
const unsigned char NXDN_LICH_STEAL_NONE = 3U;
|
||||||
const unsigned char NXDN_LICH_STEAL_FACCH1_2 = 2U;
|
const unsigned char NXDN_LICH_STEAL_FACCH1_2 = 2U;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2014,2016,2018-2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2014,2016,2018-2020,2025 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
|
||||||
|
|
@ -76,20 +76,20 @@ bool CNXDNIcomNetwork::write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYP
|
||||||
buffer[7U] = 0xE0U;
|
buffer[7U] = 0xE0U;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NNMT_VOICE_HEADER:
|
case NXDN_NETWORK_MESSAGE_TYPE::VOICE_HEADER:
|
||||||
case NNMT_VOICE_TRAILER:
|
case NXDN_NETWORK_MESSAGE_TYPE::VOICE_TRAILER:
|
||||||
buffer[37U] = 0x23U;
|
buffer[37U] = 0x23U;
|
||||||
buffer[38U] = 0x1CU;
|
buffer[38U] = 0x1CU;
|
||||||
buffer[39U] = 0x21U;
|
buffer[39U] = 0x21U;
|
||||||
break;
|
break;
|
||||||
case NNMT_VOICE_BODY:
|
case NXDN_NETWORK_MESSAGE_TYPE::VOICE_BODY:
|
||||||
buffer[37U] = 0x23U;
|
buffer[37U] = 0x23U;
|
||||||
buffer[38U] = 0x10U;
|
buffer[38U] = 0x10U;
|
||||||
buffer[39U] = 0x21U;
|
buffer[39U] = 0x21U;
|
||||||
break;
|
break;
|
||||||
case NNMT_DATA_HEADER:
|
case NXDN_NETWORK_MESSAGE_TYPE::DATA_HEADER:
|
||||||
case NNMT_DATA_BODY:
|
case NXDN_NETWORK_MESSAGE_TYPE::DATA_BODY:
|
||||||
case NNMT_DATA_TRAILER:
|
case NXDN_NETWORK_MESSAGE_TYPE::DATA_TRAILER:
|
||||||
buffer[37U] = 0x23U;
|
buffer[37U] = 0x23U;
|
||||||
buffer[38U] = 0x02U;
|
buffer[38U] = 0x02U;
|
||||||
buffer[39U] = 0x18U;
|
buffer[39U] = 0x18U;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2014,2016,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2014,2016,2018,2020,2025 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
|
||||||
|
|
@ -110,15 +110,15 @@ bool CNXDNKenwoodNetwork::write(const unsigned char* data, NXDN_NETWORK_MESSAGE_
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NNMT_VOICE_HEADER: // Voice header or trailer
|
case NXDN_NETWORK_MESSAGE_TYPE::VOICE_HEADER: // Voice header or trailer
|
||||||
case NNMT_VOICE_TRAILER:
|
case NXDN_NETWORK_MESSAGE_TYPE::VOICE_TRAILER:
|
||||||
return processIcomVoiceHeader(data);
|
return processIcomVoiceHeader(data);
|
||||||
case NNMT_VOICE_BODY: // Voice data
|
case NXDN_NETWORK_MESSAGE_TYPE::VOICE_BODY: // Voice data
|
||||||
return processIcomVoiceData(data);
|
return processIcomVoiceData(data);
|
||||||
case NNMT_DATA_HEADER: // Data header or trailer
|
case NXDN_NETWORK_MESSAGE_TYPE::DATA_HEADER: // Data header or trailer
|
||||||
case NNMT_DATA_TRAILER:
|
case NXDN_NETWORK_MESSAGE_TYPE::DATA_TRAILER:
|
||||||
return processIcomDataHeader(data);
|
return processIcomDataHeader(data);
|
||||||
case NNMT_DATA_BODY: // Data data
|
case NXDN_NETWORK_MESSAGE_TYPE::DATA_BODY: // Data data
|
||||||
return processIcomDataData(data);
|
return processIcomDataData(data);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -774,7 +774,7 @@ unsigned int CNXDNKenwoodNetwork::readRTP(unsigned char* data)
|
||||||
if (length <= 0)
|
if (length <= 0)
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
||||||
if (!CUDPSocket::match(m_rtpAddr, address, IMT_ADDRESS_ONLY)) {
|
if (!CUDPSocket::match(m_rtpAddr, address, IPMATCHTYPE::IMT_ADDREONLY)) {
|
||||||
LogMessage("NXDN, RTP packet received from an invalid source");
|
LogMessage("NXDN, RTP packet received from an invalid source");
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
|
@ -802,7 +802,7 @@ unsigned int CNXDNKenwoodNetwork::readRTCP(unsigned char* data)
|
||||||
if (length <= 0)
|
if (length <= 0)
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
||||||
if (!CUDPSocket::match(m_rtpAddr, address, IMT_ADDRESS_ONLY)) {
|
if (!CUDPSocket::match(m_rtpAddr, address, IPMATCHTYPE::IMT_ADDREONLY)) {
|
||||||
LogMessage("NXDN, RTCP packet received from an invalid source");
|
LogMessage("NXDN, RTCP packet received from an invalid source");
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2020,2025 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
|
||||||
|
|
@ -23,13 +23,13 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
enum NXDN_NETWORK_MESSAGE_TYPE {
|
enum class NXDN_NETWORK_MESSAGE_TYPE {
|
||||||
NNMT_VOICE_HEADER,
|
VOICE_HEADER,
|
||||||
NNMT_VOICE_BODY,
|
VOICE_BODY,
|
||||||
NNMT_VOICE_TRAILER,
|
VOICE_TRAILER,
|
||||||
NNMT_DATA_HEADER,
|
DATA_HEADER,
|
||||||
NNMT_DATA_BODY,
|
DATA_BODY,
|
||||||
NNMT_DATA_TRAILER
|
DATA_TRAILER
|
||||||
};
|
};
|
||||||
|
|
||||||
class INXDNNetwork {
|
class INXDNNetwork {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2025 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2017 by Lieven De Samblanx ON7LDS
|
* Copyright (C) 2017 by Lieven De Samblanx ON7LDS
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -123,7 +124,7 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info)
|
||||||
struct rt_msghdr *rtm;
|
struct rt_msghdr *rtm;
|
||||||
for (char *p = buf; p < buf + size; p += rtm->rtm_msglen) {
|
for (char *p = buf; p < buf + size; p += rtm->rtm_msglen) {
|
||||||
rtm = (struct rt_msghdr *)p;
|
rtm = (struct rt_msghdr *)p;
|
||||||
if (rtm->rtm_version != RTM_VERSION)
|
if (rtm->rtm_version != VERSION)
|
||||||
continue;
|
continue;
|
||||||
#if defined(__OpenBSD__)
|
#if defined(__OpenBSD__)
|
||||||
struct sockaddr_in *sa = (struct sockaddr_in *)(p + rtm->rtm_hdrlen);
|
struct sockaddr_in *sa = (struct sockaddr_in *)(p + rtm->rtm_hdrlen);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016-2019,2021,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016-2019,2021,2024,2025 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2018 by Bryan Biedenkapp <gatekeep@gmail.com> N2PLL
|
* Copyright (C) 2018 by Bryan Biedenkapp <gatekeep@gmail.com> N2PLL
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -49,8 +49,8 @@ m_display(display),
|
||||||
m_duplex(duplex),
|
m_duplex(duplex),
|
||||||
m_lookup(lookup),
|
m_lookup(lookup),
|
||||||
m_queue(1000U, "P25 Control"),
|
m_queue(1000U, "P25 Control"),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RPT_RF_STATE::LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RPT_NET_STATE::IDLE),
|
||||||
m_rfTimeout(1000U, timeout),
|
m_rfTimeout(1000U, timeout),
|
||||||
m_netTimeout(1000U, timeout),
|
m_netTimeout(1000U, timeout),
|
||||||
m_networkWatchdog(1000U, 0U, 1500U),
|
m_networkWatchdog(1000U, 0U, 1500U),
|
||||||
|
|
@ -124,7 +124,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
|
|
||||||
bool sync = data[1U] == 0x01U;
|
bool sync = data[1U] == 0x01U;
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if ((data[0U] == TAG_LOST) && (m_rfState == RPT_RF_STATE::AUDIO)) {
|
||||||
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
|
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
|
||||||
unsigned int dstId = m_rfData.getDstId();
|
unsigned int dstId = m_rfData.getDstId();
|
||||||
std::string source = m_lookup->find(m_rfData.getSrcId());
|
std::string source = m_lookup->find(m_rfData.getSrcId());
|
||||||
|
|
@ -136,12 +136,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
|
|
||||||
// LogMessage("P25, total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_rfFrames, m_rfBits, m_rfUndecodableLC, m_rfErrs, float(m_rfErrs * 100U) / float(m_rfBits));
|
// LogMessage("P25, total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_rfFrames, m_rfBits, m_rfUndecodableLC, m_rfErrs, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE)
|
if (m_netState == RPT_NET_STATE::IDLE)
|
||||||
m_display->clearP25();
|
m_display->clearP25();
|
||||||
|
|
||||||
writeNetwork(m_rfLDU, m_lastDUID, true);
|
writeNetwork(m_rfLDU, m_lastDUID, true);
|
||||||
writeNetwork(data + 2U, P25_DUID_TERM, true);
|
writeNetwork(data + 2U, P25_DUID_TERM, true);
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfTimeout.stop();
|
m_rfTimeout.stop();
|
||||||
m_rfData.reset();
|
m_rfData.reset();
|
||||||
#if defined(DUMP_P25)
|
#if defined(DUMP_P25)
|
||||||
|
|
@ -150,11 +150,11 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_DATA) {
|
if ((data[0U] == TAG_LOST) && (m_rfState == RPT_RF_STATE::DATA)) {
|
||||||
if (m_netState == RS_NET_IDLE)
|
if (m_netState == RPT_NET_STATE::IDLE)
|
||||||
m_display->clearP25();
|
m_display->clearP25();
|
||||||
|
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfPDUCount = 0U;
|
m_rfPDUCount = 0U;
|
||||||
m_rfPDUBits = 0U;
|
m_rfPDUBits = 0U;
|
||||||
#if defined(DUMP_P25)
|
#if defined(DUMP_P25)
|
||||||
|
|
@ -164,17 +164,17 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST) {
|
if (data[0U] == TAG_LOST) {
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sync && m_rfState == RS_RF_LISTENING)
|
if (!sync && (m_rfState == RPT_RF_STATE::LISTENING))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Decode the NID
|
// Decode the NID
|
||||||
bool valid = m_nid.decode(data + 2U);
|
bool valid = m_nid.decode(data + 2U);
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING && !valid)
|
if ((m_rfState == RPT_RF_STATE::LISTENING) && !valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char duid = m_nid.getDUID();
|
unsigned char duid = m_nid.getDUID();
|
||||||
|
|
@ -222,7 +222,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duid == P25_DUID_HEADER) {
|
if (duid == P25_DUID_HEADER) {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
m_rfData.reset();
|
m_rfData.reset();
|
||||||
bool ret = m_rfData.decodeHeader(data + 2U);
|
bool ret = m_rfData.decodeHeader(data + 2U);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
|
@ -236,7 +236,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (duid == P25_DUID_LDU1) {
|
} else if (duid == P25_DUID_LDU1) {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
m_rfData.reset();
|
m_rfData.reset();
|
||||||
bool ret = m_rfData.decodeLDU1(data + 2U);
|
bool ret = m_rfData.decodeLDU1(data + 2U);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
|
@ -275,7 +275,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
LogMessage("P25, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
LogMessage("P25, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||||
m_display->writeP25(source.c_str(), grp, dstId, "R");
|
m_display->writeP25(source.c_str(), grp, dstId, "R");
|
||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
|
|
@ -284,11 +284,11 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
|
|
||||||
createRFHeader();
|
createRFHeader();
|
||||||
writeNetwork(data + 2U, P25_DUID_HEADER, false);
|
writeNetwork(data + 2U, P25_DUID_HEADER, false);
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
} else if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
writeNetwork(m_rfLDU, m_lastDUID, false);
|
writeNetwork(m_rfLDU, m_lastDUID, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
/*
|
/*
|
||||||
bool ret = m_rfData.decodeLDU1(data + 2U);
|
bool ret = m_rfData.decodeLDU1(data + 2U);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
|
@ -342,7 +342,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (duid == P25_DUID_LDU2) {
|
} else if (duid == P25_DUID_LDU2) {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
/*
|
/*
|
||||||
bool ret = m_rfData.decodeLDU2(data + 2U);
|
bool ret = m_rfData.decodeLDU2(data + 2U);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
|
@ -398,10 +398,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (duid == P25_DUID_TSDU) {
|
} else if (duid == P25_DUID_TSDU) {
|
||||||
if (m_rfState != RS_RF_DATA) {
|
if (m_rfState != RPT_RF_STATE::DATA) {
|
||||||
m_rfPDUCount = 0U;
|
m_rfPDUCount = 0U;
|
||||||
m_rfPDUBits = 0U;
|
m_rfPDUBits = 0U;
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
m_rfDataFrames = 0U;
|
m_rfDataFrames = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,10 +475,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return true;
|
return true;
|
||||||
} else if (duid == P25_DUID_TERM || duid == P25_DUID_TERM_LC) {
|
} else if (duid == P25_DUID_TERM || duid == P25_DUID_TERM_LC) {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
writeNetwork(m_rfLDU, m_lastDUID, true);
|
writeNetwork(m_rfLDU, m_lastDUID, true);
|
||||||
|
|
||||||
::memset(data + 2U, 0x00U, P25_TERM_FRAME_LENGTH_BYTES);
|
::memset(data + 2U, 0x00U, P25_TERM_FRAME_LENGTH_BYTES);
|
||||||
|
|
@ -496,7 +496,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
unsigned int dstId = m_rfData.getDstId();
|
unsigned int dstId = m_rfData.getDstId();
|
||||||
std::string source = m_lookup->find(m_rfData.getSrcId());
|
std::string source = m_lookup->find(m_rfData.getSrcId());
|
||||||
|
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfTimeout.stop();
|
m_rfTimeout.stop();
|
||||||
m_rfData.reset();
|
m_rfData.reset();
|
||||||
m_lastDUID = duid;
|
m_lastDUID = duid;
|
||||||
|
|
@ -523,10 +523,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (duid == P25_DUID_PDU) {
|
} else if (duid == P25_DUID_PDU) {
|
||||||
if (m_rfState != RS_RF_DATA) {
|
if (m_rfState != RPT_RF_STATE::DATA) {
|
||||||
m_rfPDUCount = 0U;
|
m_rfPDUCount = 0U;
|
||||||
m_rfPDUBits = 0U;
|
m_rfPDUBits = 0U;
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
m_rfDataFrames = 0U;
|
m_rfDataFrames = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -556,12 +556,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
} else {
|
} else {
|
||||||
m_rfPDUCount = 0U;
|
m_rfPDUCount = 0U;
|
||||||
m_rfPDUBits = 0U;
|
m_rfPDUBits = 0U;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfDataFrames = 0U;
|
m_rfDataFrames = 0U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_DATA) {
|
if (m_rfState == RPT_RF_STATE::DATA) {
|
||||||
m_rfPDUCount++;
|
m_rfPDUCount++;
|
||||||
|
|
||||||
unsigned int bitLength = ((m_rfDataFrames + 1U) * P25_PDU_FEC_LENGTH_BITS) + P25_SYNC_LENGTH_BITS + P25_NID_LENGTH_BITS;
|
unsigned int bitLength = ((m_rfDataFrames + 1U) * P25_PDU_FEC_LENGTH_BITS) + P25_SYNC_LENGTH_BITS + P25_NID_LENGTH_BITS;
|
||||||
|
|
@ -620,7 +620,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
|
|
||||||
m_rfPDUCount = 0U;
|
m_rfPDUCount = 0U;
|
||||||
m_rfPDUBits = 0U;
|
m_rfPDUBits = 0U;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfDataFrames = 0U;
|
m_rfDataFrames = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -660,7 +660,7 @@ void CP25Control::writeNetwork()
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
if ((m_rfState != RPT_RF_STATE::LISTENING) && (m_netState == RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
@ -701,7 +701,7 @@ void CP25Control::writeNetwork()
|
||||||
case 0x6AU:
|
case 0x6AU:
|
||||||
::memcpy(m_netLDU1 + 200U, data, 16U);
|
::memcpy(m_netLDU1 + 200U, data, 16U);
|
||||||
checkNetLDU2();
|
checkNetLDU2();
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
createNetLDU1();
|
createNetLDU1();
|
||||||
break;
|
break;
|
||||||
case 0x6BU:
|
case 0x6BU:
|
||||||
|
|
@ -738,7 +738,7 @@ void CP25Control::writeNetwork()
|
||||||
break;
|
break;
|
||||||
case 0x73U:
|
case 0x73U:
|
||||||
::memcpy(m_netLDU2 + 200U, data, 16U);
|
::memcpy(m_netLDU2 + 200U, data, 16U);
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
createNetHeader();
|
createNetHeader();
|
||||||
createNetLDU1();
|
createNetLDU1();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -762,14 +762,14 @@ void CP25Control::clock(unsigned int ms)
|
||||||
m_rfTimeout.clock(ms);
|
m_rfTimeout.clock(ms);
|
||||||
m_netTimeout.clock(ms);
|
m_netTimeout.clock(ms);
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
LogMessage("P25, network watchdog has expired, %.1f seconds, %u%% packet loss", float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames);
|
LogMessage("P25, network watchdog has expired, %.1f seconds, %u%% packet loss", float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames);
|
||||||
m_display->clearP25();
|
m_display->clearP25();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
m_netData.reset();
|
m_netData.reset();
|
||||||
m_netTimeout.stop();
|
m_netTimeout.stop();
|
||||||
}
|
}
|
||||||
|
|
@ -849,7 +849,7 @@ void CP25Control::addBusyBits(unsigned char* data, unsigned int length, bool b1,
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
for (unsigned int ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += P25_SS_INCREMENT) {
|
for (unsigned int ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += P25_INCREMENT) {
|
||||||
unsigned int ss1Pos = ss0Pos + 1U;
|
unsigned int ss1Pos = ss0Pos + 1U;
|
||||||
WRITE_BIT(data, ss0Pos, b1);
|
WRITE_BIT(data, ss0Pos, b1);
|
||||||
WRITE_BIT(data, ss1Pos, b2);
|
WRITE_BIT(data, ss1Pos, b2);
|
||||||
|
|
@ -858,7 +858,7 @@ void CP25Control::addBusyBits(unsigned char* data, unsigned int length, bool b1,
|
||||||
|
|
||||||
void CP25Control::checkNetLDU1()
|
void CP25Control::checkNetLDU1()
|
||||||
{
|
{
|
||||||
if (m_netState == RS_NET_IDLE)
|
if (m_netState == RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for an unflushed LDU1
|
// Check for an unflushed LDU1
|
||||||
|
|
@ -870,7 +870,7 @@ void CP25Control::checkNetLDU1()
|
||||||
|
|
||||||
void CP25Control::checkNetLDU2()
|
void CP25Control::checkNetLDU2()
|
||||||
{
|
{
|
||||||
if (m_netState == RS_NET_IDLE)
|
if (m_netState == RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for an unflushed LDU1
|
// Check for an unflushed LDU1
|
||||||
|
|
@ -1018,7 +1018,7 @@ void CP25Control::createNetHeader()
|
||||||
|
|
||||||
m_display->writeP25(source.c_str(), lcf == P25_LCF_GROUP, dstId, "N");
|
m_display->writeP25(source.c_str(), lcf == P25_LCF_GROUP, dstId, "N");
|
||||||
|
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
m_netTimeout.start();
|
m_netTimeout.start();
|
||||||
m_netFrames = 0U;
|
m_netFrames = 0U;
|
||||||
m_netLost = 0U;
|
m_netLost = 0U;
|
||||||
|
|
@ -1193,7 +1193,7 @@ void CP25Control::createNetTerminator()
|
||||||
m_netTimeout.stop();
|
m_netTimeout.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
m_netData.reset();
|
m_netData.reset();
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CP25Control::openFile()
|
bool CP25Control::openFile()
|
||||||
|
|
@ -1240,7 +1240,7 @@ void CP25Control::closeFile()
|
||||||
|
|
||||||
bool CP25Control::isBusy() const
|
bool CP25Control::isBusy() const
|
||||||
{
|
{
|
||||||
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
|
return (m_rfState != RPT_RF_STATE::LISTENING) || (m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25Control::enable(bool enabled)
|
void CP25Control::enable(bool enabled)
|
||||||
|
|
@ -1249,7 +1249,7 @@ void CP25Control::enable(bool enabled)
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
|
|
||||||
// Reset the RF section
|
// Reset the RF section
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
m_rfTimeout.stop();
|
m_rfTimeout.stop();
|
||||||
m_rfData.reset();
|
m_rfData.reset();
|
||||||
|
|
||||||
|
|
@ -1257,7 +1257,7 @@ void CP25Control::enable(bool enabled)
|
||||||
m_netTimeout.stop();
|
m_netTimeout.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
m_netData.reset();
|
m_netData.reset();
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2025 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2018 by Bryan Biedenkapp <gatekeep@gmail.com>
|
* Copyright (C) 2018 by Bryan Biedenkapp <gatekeep@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -65,7 +65,7 @@ const unsigned char P25_LCF_TSBK_ACK_RSP_FNE = 0x20U;
|
||||||
|
|
||||||
const unsigned int P25_SS0_START = 70U;
|
const unsigned int P25_SS0_START = 70U;
|
||||||
const unsigned int P25_SS1_START = 71U;
|
const unsigned int P25_SS1_START = 71U;
|
||||||
const unsigned int P25_SS_INCREMENT = 72U;
|
const unsigned int P25_INCREMENT = 72U;
|
||||||
|
|
||||||
const unsigned char P25_DUID_HEADER = 0x00U;
|
const unsigned char P25_DUID_HEADER = 0x00U;
|
||||||
const unsigned char P25_DUID_TERM = 0x03U;
|
const unsigned char P25_DUID_TERM = 0x03U;
|
||||||
|
|
|
||||||
22
P25Utils.cpp
22
P25Utils.cpp
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2018,2025 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
|
||||||
|
|
@ -37,16 +37,16 @@ unsigned int CP25Utils::decode(const unsigned char* in, unsigned char* out, unsi
|
||||||
unsigned int ss1Pos = P25_SS1_START;
|
unsigned int ss1Pos = P25_SS1_START;
|
||||||
|
|
||||||
while (ss0Pos < start) {
|
while (ss0Pos < start) {
|
||||||
ss0Pos += P25_SS_INCREMENT;
|
ss0Pos += P25_INCREMENT;
|
||||||
ss1Pos += P25_SS_INCREMENT;
|
ss1Pos += P25_INCREMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int n = 0U;
|
unsigned int n = 0U;
|
||||||
for (unsigned int i = start; i < stop; i++) {
|
for (unsigned int i = start; i < stop; i++) {
|
||||||
if (i == ss0Pos) {
|
if (i == ss0Pos) {
|
||||||
ss0Pos += P25_SS_INCREMENT;
|
ss0Pos += P25_INCREMENT;
|
||||||
} else if (i == ss1Pos) {
|
} else if (i == ss1Pos) {
|
||||||
ss1Pos += P25_SS_INCREMENT;
|
ss1Pos += P25_INCREMENT;
|
||||||
} else {
|
} else {
|
||||||
bool b = READ_BIT(in, i);
|
bool b = READ_BIT(in, i);
|
||||||
WRITE_BIT(out, n, b);
|
WRITE_BIT(out, n, b);
|
||||||
|
|
@ -67,16 +67,16 @@ unsigned int CP25Utils::encode(const unsigned char* in, unsigned char* out, unsi
|
||||||
unsigned int ss1Pos = P25_SS1_START;
|
unsigned int ss1Pos = P25_SS1_START;
|
||||||
|
|
||||||
while (ss0Pos < start) {
|
while (ss0Pos < start) {
|
||||||
ss0Pos += P25_SS_INCREMENT;
|
ss0Pos += P25_INCREMENT;
|
||||||
ss1Pos += P25_SS_INCREMENT;
|
ss1Pos += P25_INCREMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int n = 0U;
|
unsigned int n = 0U;
|
||||||
for (unsigned int i = start; i < stop; i++) {
|
for (unsigned int i = start; i < stop; i++) {
|
||||||
if (i == ss0Pos) {
|
if (i == ss0Pos) {
|
||||||
ss0Pos += P25_SS_INCREMENT;
|
ss0Pos += P25_INCREMENT;
|
||||||
} else if (i == ss1Pos) {
|
} else if (i == ss1Pos) {
|
||||||
ss1Pos += P25_SS_INCREMENT;
|
ss1Pos += P25_INCREMENT;
|
||||||
} else {
|
} else {
|
||||||
bool b = READ_BIT(in, n);
|
bool b = READ_BIT(in, n);
|
||||||
WRITE_BIT(out, i, b);
|
WRITE_BIT(out, i, b);
|
||||||
|
|
@ -100,9 +100,9 @@ unsigned int CP25Utils::encode(const unsigned char* in, unsigned char* out, unsi
|
||||||
unsigned int pos = 0U;
|
unsigned int pos = 0U;
|
||||||
while (n < length) {
|
while (n < length) {
|
||||||
if (pos == ss0Pos) {
|
if (pos == ss0Pos) {
|
||||||
ss0Pos += P25_SS_INCREMENT;
|
ss0Pos += P25_INCREMENT;
|
||||||
} else if (pos == ss1Pos) {
|
} else if (pos == ss1Pos) {
|
||||||
ss1Pos += P25_SS_INCREMENT;
|
ss1Pos += P25_INCREMENT;
|
||||||
} else {
|
} else {
|
||||||
bool b = READ_BIT(in, n);
|
bool b = READ_BIT(in, n);
|
||||||
WRITE_BIT(out, pos, b);
|
WRITE_BIT(out, pos, b);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018,2019,2020 Jonathan Naylor, G4KLX
|
* Copyright (C) 2018,2019,2020,2025 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
|
||||||
|
|
@ -68,7 +68,7 @@ m_output(),
|
||||||
m_buffer(),
|
m_buffer(),
|
||||||
m_ric(0U),
|
m_ric(0U),
|
||||||
m_data(),
|
m_data(),
|
||||||
m_state(PS_NONE),
|
m_state(POCSAG_STATE::NONE),
|
||||||
m_enabled(true),
|
m_enabled(true),
|
||||||
m_fp(NULL)
|
m_fp(NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -289,7 +289,7 @@ bool CPOCSAGControl::processData()
|
||||||
|
|
||||||
void CPOCSAGControl::clock(unsigned int ms)
|
void CPOCSAGControl::clock(unsigned int ms)
|
||||||
{
|
{
|
||||||
if (m_state == PS_NONE) {
|
if (m_state == POCSAG_STATE::NONE) {
|
||||||
bool ret = readNetwork();
|
bool ret = readNetwork();
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
@ -298,7 +298,7 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_state = PS_WAITING;
|
m_state = POCSAG_STATE::WAITING;
|
||||||
m_frames = 0U;
|
m_frames = 0U;
|
||||||
m_count = 1U;
|
m_count = 1U;
|
||||||
|
|
||||||
|
|
@ -311,7 +311,7 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
m_output.push_back(POCSAG_SYNC_WORD);
|
m_output.push_back(POCSAG_SYNC_WORD);
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < POCSAG_FRAME_ADDRESSES; i++) {
|
for (unsigned int i = 0U; i < POCSAG_FRAME_ADDRESSES; i++) {
|
||||||
if (m_state == PS_WAITING) {
|
if (m_state == POCSAG_STATE::WAITING) {
|
||||||
if (i == (m_ric % POCSAG_FRAME_ADDRESSES)) {
|
if (i == (m_ric % POCSAG_FRAME_ADDRESSES)) {
|
||||||
uint32_t w1 = m_buffer.front();
|
uint32_t w1 = m_buffer.front();
|
||||||
m_buffer.pop_front();
|
m_buffer.pop_front();
|
||||||
|
|
@ -321,22 +321,22 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
m_output.push_back(w1);
|
m_output.push_back(w1);
|
||||||
m_output.push_back(w2);
|
m_output.push_back(w2);
|
||||||
|
|
||||||
m_state = PS_SENDING;
|
m_state = POCSAG_STATE::SENDING;
|
||||||
} else {
|
} else {
|
||||||
m_output.push_back(POCSAG_IDLE_WORD);
|
m_output.push_back(POCSAG_IDLE_WORD);
|
||||||
m_output.push_back(POCSAG_IDLE_WORD);
|
m_output.push_back(POCSAG_IDLE_WORD);
|
||||||
}
|
}
|
||||||
} else if (m_state == PS_SENDING) {
|
} else if (m_state == POCSAG_STATE::SENDING) {
|
||||||
if (m_buffer.empty()) {
|
if (m_buffer.empty()) {
|
||||||
m_output.push_back(POCSAG_IDLE_WORD);
|
m_output.push_back(POCSAG_IDLE_WORD);
|
||||||
m_output.push_back(POCSAG_IDLE_WORD);
|
m_output.push_back(POCSAG_IDLE_WORD);
|
||||||
|
|
||||||
bool ret = processData();
|
bool ret = processData();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
m_state = PS_WAITING;
|
m_state = POCSAG_STATE::WAITING;
|
||||||
m_count++;
|
m_count++;
|
||||||
} else {
|
} else {
|
||||||
m_state = PS_ENDING;
|
m_state = POCSAG_STATE::ENDING;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint32_t w1 = m_buffer.front();
|
uint32_t w1 = m_buffer.front();
|
||||||
|
|
@ -347,7 +347,7 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
m_output.push_back(w1);
|
m_output.push_back(w1);
|
||||||
m_output.push_back(w2);
|
m_output.push_back(w2);
|
||||||
}
|
}
|
||||||
} else { // PS_ENDING
|
} else { // ENDING
|
||||||
m_output.push_back(POCSAG_IDLE_WORD);
|
m_output.push_back(POCSAG_IDLE_WORD);
|
||||||
m_output.push_back(POCSAG_IDLE_WORD);
|
m_output.push_back(POCSAG_IDLE_WORD);
|
||||||
}
|
}
|
||||||
|
|
@ -356,10 +356,10 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
writeQueue();
|
writeQueue();
|
||||||
m_frames++;
|
m_frames++;
|
||||||
|
|
||||||
if (m_state == PS_ENDING) {
|
if (m_state == POCSAG_STATE::ENDING) {
|
||||||
LogMessage("POCSAG, transmitted %u frame(s) of data from %u message(s)", m_frames, m_count);
|
LogMessage("POCSAG, transmitted %u frame(s) of data from %u message(s)", m_frames, m_count);
|
||||||
m_display->clearPOCSAG();
|
m_display->clearPOCSAG();
|
||||||
m_state = PS_NONE;
|
m_state = POCSAG_STATE::NONE;
|
||||||
|
|
||||||
#if defined(DUMP_POCSAG)
|
#if defined(DUMP_POCSAG)
|
||||||
closeFile();
|
closeFile();
|
||||||
|
|
@ -568,7 +568,7 @@ void CPOCSAGControl::enable(bool enabled)
|
||||||
delete *it;
|
delete *it;
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
|
|
||||||
m_state = PS_NONE;
|
m_state = POCSAG_STATE::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018,2019,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2018,2019,2020,2025 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
|
||||||
|
|
@ -60,11 +60,11 @@ private:
|
||||||
unsigned int m_frames;
|
unsigned int m_frames;
|
||||||
unsigned int m_count;
|
unsigned int m_count;
|
||||||
|
|
||||||
enum POCSAG_STATE {
|
enum class POCSAG_STATE {
|
||||||
PS_NONE,
|
NONE,
|
||||||
PS_WAITING,
|
WAITING,
|
||||||
PS_SENDING,
|
SENDING,
|
||||||
PS_ENDING
|
ENDING
|
||||||
};
|
};
|
||||||
|
|
||||||
std::deque<uint32_t> m_output;
|
std::deque<uint32_t> m_output;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2019,2020,2025 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
|
||||||
|
|
@ -85,7 +85,7 @@ int CRemoteCommand::send(const std::string& command)
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ret = socket.write((unsigned char*)command.c_str(), command.length(), addr, addrLen);
|
ret = socket.write((unsigned char*)command.c_str(), (unsigned int)command.length(), addr, addrLen);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
socket.close();
|
socket.close();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019,2020,2021,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2019,2020,2021,2024,2025 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
|
||||||
|
|
@ -38,7 +38,7 @@ m_host(host),
|
||||||
m_socket(address, port),
|
m_socket(address, port),
|
||||||
m_addr(),
|
m_addr(),
|
||||||
m_addrLen(0U),
|
m_addrLen(0U),
|
||||||
m_command(RCD_NONE),
|
m_command(REMOTE_COMMAND::NONE),
|
||||||
m_args()
|
m_args()
|
||||||
{
|
{
|
||||||
assert(port > 0U);
|
assert(port > 0U);
|
||||||
|
|
@ -63,7 +63,7 @@ bool CRemoteControl::open()
|
||||||
|
|
||||||
REMOTE_COMMAND CRemoteControl::getCommand()
|
REMOTE_COMMAND CRemoteControl::getCommand()
|
||||||
{
|
{
|
||||||
m_command = RCD_NONE;
|
m_command = REMOTE_COMMAND::NONE;
|
||||||
m_args.clear();
|
m_args.clear();
|
||||||
|
|
||||||
char command[BUFFER_LENGTH];
|
char command[BUFFER_LENGTH];
|
||||||
|
|
@ -89,79 +89,79 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
||||||
if (m_args.at(0U) == "mode" && m_args.size() >= SET_MODE_ARGS) {
|
if (m_args.at(0U) == "mode" && m_args.size() >= SET_MODE_ARGS) {
|
||||||
// Mode command is in the form of "mode <mode> [<timeout>|fixed]"
|
// Mode command is in the form of "mode <mode> [<timeout>|fixed]"
|
||||||
if (m_args.at(1U) == "idle")
|
if (m_args.at(1U) == "idle")
|
||||||
m_command = RCD_MODE_IDLE;
|
m_command = REMOTE_COMMAND::MODE_IDLE;
|
||||||
else if (m_args.at(1U) == "lockout")
|
else if (m_args.at(1U) == "lockout")
|
||||||
m_command = RCD_MODE_LOCKOUT;
|
m_command = REMOTE_COMMAND::MODE_LOCKOUT;
|
||||||
else if (m_args.at(1U) == "d-star")
|
else if (m_args.at(1U) == "d-star")
|
||||||
m_command = RCD_MODE_DSTAR;
|
m_command = REMOTE_COMMAND::MODE_DSTAR;
|
||||||
else if (m_args.at(1U) == "dmr")
|
else if (m_args.at(1U) == "dmr")
|
||||||
m_command = RCD_MODE_DMR;
|
m_command = REMOTE_COMMAND::MODE_DMR;
|
||||||
else if (m_args.at(1U) == "ysf")
|
else if (m_args.at(1U) == "ysf")
|
||||||
m_command = RCD_MODE_YSF;
|
m_command = REMOTE_COMMAND::MODE_YSF;
|
||||||
else if (m_args.at(1U) == "p25")
|
else if (m_args.at(1U) == "p25")
|
||||||
m_command = RCD_MODE_P25;
|
m_command = REMOTE_COMMAND::MODE_P25;
|
||||||
else if (m_args.at(1U) == "nxdn")
|
else if (m_args.at(1U) == "nxdn")
|
||||||
m_command = RCD_MODE_NXDN;
|
m_command = REMOTE_COMMAND::MODE_NXDN;
|
||||||
else if (m_args.at(1U) == "m17")
|
else if (m_args.at(1U) == "m17")
|
||||||
m_command = RCD_MODE_M17;
|
m_command = REMOTE_COMMAND::MODE_M17;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
} else if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
} else if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
||||||
if (m_args.at(1U) == "dstar")
|
if (m_args.at(1U) == "dstar")
|
||||||
m_command = RCD_ENABLE_DSTAR;
|
m_command = REMOTE_COMMAND::ENABLE_DSTAR;
|
||||||
else if (m_args.at(1U) == "dmr")
|
else if (m_args.at(1U) == "dmr")
|
||||||
m_command = RCD_ENABLE_DMR;
|
m_command = REMOTE_COMMAND::ENABLE_DMR;
|
||||||
else if (m_args.at(1U) == "ysf")
|
else if (m_args.at(1U) == "ysf")
|
||||||
m_command = RCD_ENABLE_YSF;
|
m_command = REMOTE_COMMAND::ENABLE_YSF;
|
||||||
else if (m_args.at(1U) == "p25")
|
else if (m_args.at(1U) == "p25")
|
||||||
m_command = RCD_ENABLE_P25;
|
m_command = REMOTE_COMMAND::ENABLE_P25;
|
||||||
else if (m_args.at(1U) == "nxdn")
|
else if (m_args.at(1U) == "nxdn")
|
||||||
m_command = RCD_ENABLE_NXDN;
|
m_command = REMOTE_COMMAND::ENABLE_NXDN;
|
||||||
else if (m_args.at(1U) == "m17")
|
else if (m_args.at(1U) == "m17")
|
||||||
m_command = RCD_ENABLE_M17;
|
m_command = REMOTE_COMMAND::ENABLE_M17;
|
||||||
else if (m_args.at(1U) == "fm")
|
else if (m_args.at(1U) == "fm")
|
||||||
m_command = RCD_ENABLE_FM;
|
m_command = REMOTE_COMMAND::ENABLE_FM;
|
||||||
else if (m_args.at(1U) == "ax25")
|
else if (m_args.at(1U) == "ax25")
|
||||||
m_command = RCD_ENABLE_AX25;
|
m_command = REMOTE_COMMAND::ENABLE_AX25;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
} else if (m_args.at(0U) == "disable" && m_args.size() >= DISABLE_ARGS) {
|
} else if (m_args.at(0U) == "disable" && m_args.size() >= DISABLE_ARGS) {
|
||||||
if (m_args.at(1U) == "dstar")
|
if (m_args.at(1U) == "dstar")
|
||||||
m_command = RCD_DISABLE_DSTAR;
|
m_command = REMOTE_COMMAND::DISABLE_DSTAR;
|
||||||
else if (m_args.at(1U) == "dmr")
|
else if (m_args.at(1U) == "dmr")
|
||||||
m_command = RCD_DISABLE_DMR;
|
m_command = REMOTE_COMMAND::DISABLE_DMR;
|
||||||
else if (m_args.at(1U) == "ysf")
|
else if (m_args.at(1U) == "ysf")
|
||||||
m_command = RCD_DISABLE_YSF;
|
m_command = REMOTE_COMMAND::DISABLE_YSF;
|
||||||
else if (m_args.at(1U) == "p25")
|
else if (m_args.at(1U) == "p25")
|
||||||
m_command = RCD_DISABLE_P25;
|
m_command = REMOTE_COMMAND::DISABLE_P25;
|
||||||
else if (m_args.at(1U) == "nxdn")
|
else if (m_args.at(1U) == "nxdn")
|
||||||
m_command = RCD_DISABLE_NXDN;
|
m_command = REMOTE_COMMAND::DISABLE_NXDN;
|
||||||
else if (m_args.at(1U) == "m17")
|
else if (m_args.at(1U) == "m17")
|
||||||
m_command = RCD_DISABLE_M17;
|
m_command = REMOTE_COMMAND::DISABLE_M17;
|
||||||
else if (m_args.at(1U) == "fm")
|
else if (m_args.at(1U) == "fm")
|
||||||
m_command = RCD_DISABLE_FM;
|
m_command = REMOTE_COMMAND::DISABLE_FM;
|
||||||
else if (m_args.at(1U) == "ax25")
|
else if (m_args.at(1U) == "ax25")
|
||||||
m_command = RCD_DISABLE_AX25;
|
m_command = REMOTE_COMMAND::DISABLE_AX25;
|
||||||
else
|
else
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
} else if (m_args.at(0U) == "page" && m_args.size() >= PAGE_ARGS) {
|
} else if (m_args.at(0U) == "page" && m_args.size() >= PAGE_ARGS) {
|
||||||
// Page command is in the form of "page <ric> <message>"
|
// Page command is in the form of "page <ric> <message>"
|
||||||
m_command = RCD_PAGE;
|
m_command = REMOTE_COMMAND::PAGE;
|
||||||
} else if (m_args.at(0U) == "page_bcd" && m_args.size() >= PAGE_ARGS) {
|
} else if (m_args.at(0U) == "page_bcd" && m_args.size() >= PAGE_ARGS) {
|
||||||
// BCD page command is in the form of "page_bcd <ric> <bcd message>"
|
// BCD page command is in the form of "page_bcd <ric> <bcd message>"
|
||||||
m_command = RCD_PAGE_BCD;
|
m_command = REMOTE_COMMAND::PAGE_BCD;
|
||||||
} else if (m_args.at(0U) == "page_a1" && m_args.size() == 2) {
|
} else if (m_args.at(0U) == "page_a1" && m_args.size() == 2) {
|
||||||
// Alert1 page command is in the form of "page_a1 <ric>"
|
// Alert1 page command is in the form of "page_a1 <ric>"
|
||||||
m_command = RCD_PAGE_A1;
|
m_command = REMOTE_COMMAND::PAGE_A1;
|
||||||
} else if (m_args.at(0U) == "page_a2" && m_args.size() >= PAGE_ARGS) {
|
} else if (m_args.at(0U) == "page_a2" && m_args.size() >= PAGE_ARGS) {
|
||||||
// Alert2 page command is in the form of "page_a2 <ric> <message>"
|
// Alert2 page command is in the form of "page_a2 <ric> <message>"
|
||||||
m_command = RCD_PAGE_A2;
|
m_command = REMOTE_COMMAND::PAGE_A2;
|
||||||
} else if (m_args.at(0U) == "cw" && m_args.size() >= CW_ARGS) {
|
} else if (m_args.at(0U) == "cw" && m_args.size() >= CW_ARGS) {
|
||||||
// CW command is in the form of "cw <message>"
|
// CW command is in the form of "cw <message>"
|
||||||
m_command = RCD_CW;
|
m_command = REMOTE_COMMAND::CW;
|
||||||
} else if (m_args.at(0U) == "reload") {
|
} else if (m_args.at(0U) == "reload") {
|
||||||
// Reload command is in the form of "reload"
|
// Reload command is in the form of "reload"
|
||||||
m_command = RCD_RELOAD;
|
m_command = REMOTE_COMMAND::RELOAD;
|
||||||
} else if (m_args.at(0U) == "status") {
|
} else if (m_args.at(0U) == "status") {
|
||||||
if (m_host != NULL) {
|
if (m_host != NULL) {
|
||||||
m_host->buildNetworkStatusString(replyStr);
|
m_host->buildNetworkStatusString(replyStr);
|
||||||
|
|
@ -169,7 +169,7 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_command = RCD_CONNECTION_STATUS;
|
m_command = REMOTE_COMMAND::CONNECTION_STATUS;
|
||||||
} else if (m_args.at(0U) == "hosts") {
|
} else if (m_args.at(0U) == "hosts") {
|
||||||
if (m_host != NULL) {
|
if (m_host != NULL) {
|
||||||
m_host->buildNetworkHostsString(replyStr);
|
m_host->buildNetworkHostsString(replyStr);
|
||||||
|
|
@ -177,13 +177,13 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_command = RCD_CONFIG_HOSTS;
|
m_command = REMOTE_COMMAND::CONFIG_HOSTS;
|
||||||
} else {
|
} else {
|
||||||
replyStr = "KO";
|
replyStr = "KO";
|
||||||
}
|
}
|
||||||
|
|
||||||
::snprintf(buffer, BUFFER_LENGTH * 2, "%s remote command of \"%s\" received", ((m_command == RCD_NONE) ? "Invalid" : "Valid"), command);
|
::snprintf(buffer, BUFFER_LENGTH * 2, "%s remote command of \"%s\" received", ((m_command == REMOTE_COMMAND::NONE) ? "Invalid" : "Valid"), command);
|
||||||
if (m_command == RCD_NONE) {
|
if (m_command == REMOTE_COMMAND::NONE) {
|
||||||
m_args.clear();
|
m_args.clear();
|
||||||
LogWarning(buffer);
|
LogWarning(buffer);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -201,21 +201,21 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
||||||
unsigned int CRemoteControl::getArgCount() const
|
unsigned int CRemoteControl::getArgCount() const
|
||||||
{
|
{
|
||||||
switch (m_command) {
|
switch (m_command) {
|
||||||
case RCD_MODE_IDLE:
|
case REMOTE_COMMAND::MODE_IDLE:
|
||||||
case RCD_MODE_LOCKOUT:
|
case REMOTE_COMMAND::MODE_LOCKOUT:
|
||||||
case RCD_MODE_DSTAR:
|
case REMOTE_COMMAND::MODE_DSTAR:
|
||||||
case RCD_MODE_DMR:
|
case REMOTE_COMMAND::MODE_DMR:
|
||||||
case RCD_MODE_YSF:
|
case REMOTE_COMMAND::MODE_YSF:
|
||||||
case RCD_MODE_P25:
|
case REMOTE_COMMAND::MODE_P25:
|
||||||
case RCD_MODE_NXDN:
|
case REMOTE_COMMAND::MODE_NXDN:
|
||||||
case RCD_MODE_M17:
|
case REMOTE_COMMAND::MODE_M17:
|
||||||
return (unsigned int)m_args.size() - SET_MODE_ARGS;
|
return (unsigned int)m_args.size() - SET_MODE_ARGS;
|
||||||
case RCD_PAGE:
|
case REMOTE_COMMAND::PAGE:
|
||||||
case RCD_PAGE_BCD:
|
case REMOTE_COMMAND::PAGE_BCD:
|
||||||
case RCD_PAGE_A1:
|
case REMOTE_COMMAND::PAGE_A1:
|
||||||
case RCD_PAGE_A2:
|
case REMOTE_COMMAND::PAGE_A2:
|
||||||
return (unsigned int)m_args.size() - 1U;
|
return (unsigned int)m_args.size() - 1U;
|
||||||
case RCD_CW:
|
case REMOTE_COMMAND::CW:
|
||||||
return (unsigned int)m_args.size() - 1U;
|
return (unsigned int)m_args.size() - 1U;
|
||||||
default:
|
default:
|
||||||
return 0U;
|
return 0U;
|
||||||
|
|
@ -225,23 +225,23 @@ unsigned int CRemoteControl::getArgCount() const
|
||||||
std::string CRemoteControl::getArgString(unsigned int n) const
|
std::string CRemoteControl::getArgString(unsigned int n) const
|
||||||
{
|
{
|
||||||
switch (m_command) {
|
switch (m_command) {
|
||||||
case RCD_MODE_IDLE:
|
case REMOTE_COMMAND::MODE_IDLE:
|
||||||
case RCD_MODE_LOCKOUT:
|
case REMOTE_COMMAND::MODE_LOCKOUT:
|
||||||
case RCD_MODE_DSTAR:
|
case REMOTE_COMMAND::MODE_DSTAR:
|
||||||
case RCD_MODE_DMR:
|
case REMOTE_COMMAND::MODE_DMR:
|
||||||
case RCD_MODE_YSF:
|
case REMOTE_COMMAND::MODE_YSF:
|
||||||
case RCD_MODE_P25:
|
case REMOTE_COMMAND::MODE_P25:
|
||||||
case RCD_MODE_NXDN:
|
case REMOTE_COMMAND::MODE_NXDN:
|
||||||
case RCD_MODE_M17:
|
case REMOTE_COMMAND::MODE_M17:
|
||||||
n += SET_MODE_ARGS;
|
n += SET_MODE_ARGS;
|
||||||
break;
|
break;
|
||||||
case RCD_PAGE:
|
case REMOTE_COMMAND::PAGE:
|
||||||
case RCD_PAGE_BCD:
|
case REMOTE_COMMAND::PAGE_BCD:
|
||||||
case RCD_PAGE_A1:
|
case REMOTE_COMMAND::PAGE_A1:
|
||||||
case RCD_PAGE_A2:
|
case REMOTE_COMMAND::PAGE_A2:
|
||||||
n += 1U;
|
n += 1U;
|
||||||
break;
|
break;
|
||||||
case RCD_CW:
|
case REMOTE_COMMAND::CW:
|
||||||
n += 1U;
|
n += 1U;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019,2020,2021,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2019,2020,2021,2024,2025 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
|
||||||
|
|
@ -26,41 +26,41 @@
|
||||||
|
|
||||||
class CMMDVMHost;
|
class CMMDVMHost;
|
||||||
|
|
||||||
enum REMOTE_COMMAND {
|
enum class REMOTE_COMMAND {
|
||||||
RCD_NONE,
|
NONE,
|
||||||
RCD_MODE_IDLE,
|
MODE_IDLE,
|
||||||
RCD_MODE_LOCKOUT,
|
MODE_LOCKOUT,
|
||||||
RCD_MODE_DSTAR,
|
MODE_DSTAR,
|
||||||
RCD_MODE_DMR,
|
MODE_DMR,
|
||||||
RCD_MODE_YSF,
|
MODE_YSF,
|
||||||
RCD_MODE_P25,
|
MODE_P25,
|
||||||
RCD_MODE_NXDN,
|
MODE_NXDN,
|
||||||
RCD_MODE_M17,
|
MODE_M17,
|
||||||
RCD_MODE_FM,
|
MODE_FM,
|
||||||
RCD_ENABLE_DSTAR,
|
ENABLE_DSTAR,
|
||||||
RCD_ENABLE_DMR,
|
ENABLE_DMR,
|
||||||
RCD_ENABLE_YSF,
|
ENABLE_YSF,
|
||||||
RCD_ENABLE_P25,
|
ENABLE_P25,
|
||||||
RCD_ENABLE_NXDN,
|
ENABLE_NXDN,
|
||||||
RCD_ENABLE_M17,
|
ENABLE_M17,
|
||||||
RCD_ENABLE_FM,
|
ENABLE_FM,
|
||||||
RCD_ENABLE_AX25,
|
ENABLE_AX25,
|
||||||
RCD_DISABLE_DSTAR,
|
DISABLE_DSTAR,
|
||||||
RCD_DISABLE_DMR,
|
DISABLE_DMR,
|
||||||
RCD_DISABLE_YSF,
|
DISABLE_YSF,
|
||||||
RCD_DISABLE_P25,
|
DISABLE_P25,
|
||||||
RCD_DISABLE_NXDN,
|
DISABLE_NXDN,
|
||||||
RCD_DISABLE_M17,
|
DISABLE_M17,
|
||||||
RCD_DISABLE_FM,
|
DISABLE_FM,
|
||||||
RCD_DISABLE_AX25,
|
DISABLE_AX25,
|
||||||
RCD_PAGE,
|
PAGE,
|
||||||
RCD_PAGE_BCD,
|
PAGE_BCD,
|
||||||
RCD_PAGE_A1,
|
PAGE_A1,
|
||||||
RCD_PAGE_A2,
|
PAGE_A2,
|
||||||
RCD_CW,
|
CW,
|
||||||
RCD_RELOAD,
|
RELOAD,
|
||||||
RCD_CONNECTION_STATUS,
|
CONNECTION_STATUS,
|
||||||
RCD_CONFIG_HOSTS
|
CONFIG_HOSTS
|
||||||
};
|
};
|
||||||
|
|
||||||
class CRemoteControl {
|
class CRemoteControl {
|
||||||
|
|
|
||||||
8
SHA256.h
8
SHA256.h
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
|
* Copyright (C) 2005,2006,2008,2009 Free Software Foundation, Inc.
|
||||||
* Copyright (C) 2011,2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2011,2015,2016,2025 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
|
||||||
|
|
@ -22,9 +22,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
enum {
|
const unsigned int SHA256_DIGEST_SIZE = 256U / 8U;
|
||||||
SHA256_DIGEST_SIZE = 256 / 8
|
|
||||||
};
|
|
||||||
|
|
||||||
class CSHA256 {
|
class CSHA256 {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by SASANO Takayoshi JG1UAA
|
* Copyright (C) 2019 by SASANO Takayoshi JG1UAA
|
||||||
* Copyright (C) 2015,2016,2018,2019,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2018,2019,2020,2025 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
|
||||||
|
|
@ -56,18 +56,28 @@ static const struct layoutdef Layout[] = {
|
||||||
#define Y_WIDTH Layout[m_screenLayout].y_width
|
#define Y_WIDTH Layout[m_screenLayout].y_width
|
||||||
#define ROTATION Layout[m_screenLayout].rotation
|
#define ROTATION Layout[m_screenLayout].rotation
|
||||||
|
|
||||||
enum LcdColour {
|
#define COLOUR_BLACK 0
|
||||||
COLOUR_BLACK, COLOUR_RED, COLOUR_GREEN, COLOUR_BLUE,
|
#define COLOUR_RED 1
|
||||||
COLOUR_YELLOW, COLOUR_CYAN, COLOUR_MAGENTA, COLOUR_GREY,
|
#define COLOUR_GREEN 2
|
||||||
COLOUR_DARK_GREY, COLOUR_DARK_RED, COLOUR_DARK_GREEN, COLOUR_DARK_BLUE,
|
#define COLOUR_BLUE 3
|
||||||
COLOUR_DARK_YELLOW, COLOUR_DARK_CYAN, COLOUR_DARK_MAGENTA, COLOUR_WHITE
|
#define COLOUR_YELLOW 4
|
||||||
};
|
#define COLOUR_CYAN 5
|
||||||
|
#define COLOUR_MAGENTA 6
|
||||||
|
#define COLOUR_GREY 7
|
||||||
|
#define COLOUR_DARK_GREY 8
|
||||||
|
#define COLOUR_DARK_RED 9
|
||||||
|
#define COLOUR_DARK_GREEN 10
|
||||||
|
#define COLOUR_DARK_BLUE 11
|
||||||
|
#define COLOUR_DARK_YELLOW 12
|
||||||
|
#define COLOUR_DARK_CYAN 13
|
||||||
|
#define COLOUR_DARK_MAGENTA 14
|
||||||
|
#define COLOUR_WHITE 15
|
||||||
|
|
||||||
#define INFO_COLOUR COLOUR_CYAN
|
#define INFO_COLOUR COLOUR_CYAN
|
||||||
#define EXT_COLOUR COLOUR_DARK_GREEN
|
#define EXT_COLOUR COLOUR_DARK_GREEN
|
||||||
#define BG_COLOUR COLOUR_BLACK
|
#define BG_COLOUR COLOUR_BLACK
|
||||||
#define ERROR_COLOUR COLOUR_DARK_RED
|
#define ERROR_COLOUR COLOUR_DARK_RED
|
||||||
#define MODE_COLOUR COLOUR_YELLOW
|
#define MODE_COLOUR COLOUR_YELLOW
|
||||||
|
|
||||||
// MODE_FONT_SIZE should be equal or larger than STATUS_FONT_SIZE
|
// MODE_FONT_SIZE should be equal or larger than STATUS_FONT_SIZE
|
||||||
#define MODE_FONT_SIZE Layout[m_screenLayout].mode_font_size
|
#define MODE_FONT_SIZE Layout[m_screenLayout].mode_font_size
|
||||||
|
|
@ -107,6 +117,7 @@ m_duplex(duplex),
|
||||||
m_refresh(false),
|
m_refresh(false),
|
||||||
m_refreshTimer(1000U, 0U, REFRESH_PERIOD),
|
m_refreshTimer(1000U, 0U, REFRESH_PERIOD),
|
||||||
m_lineBuf(NULL),
|
m_lineBuf(NULL),
|
||||||
|
m_temp(),
|
||||||
m_screenLayout(screenLayout)
|
m_screenLayout(screenLayout)
|
||||||
{
|
{
|
||||||
assert(serial != NULL);
|
assert(serial != NULL);
|
||||||
|
|
@ -127,12 +138,6 @@ bool CTFTSurenoo::open()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_lineBuf = new char[statusLineOffset(STATUS_LINES)];
|
m_lineBuf = new char[statusLineOffset(STATUS_LINES)];
|
||||||
if (m_lineBuf == NULL) {
|
|
||||||
LogError("Cannot allocate line buffer");
|
|
||||||
m_serial->close();
|
|
||||||
delete m_serial;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lcdReset();
|
lcdReset();
|
||||||
clearScreen(BG_COLOUR);
|
clearScreen(BG_COLOUR);
|
||||||
|
|
@ -477,7 +482,7 @@ void CTFTSurenoo::refreshDisplay(void)
|
||||||
// clear display
|
// clear display
|
||||||
::snprintf(m_temp, sizeof(m_temp), "BOXF(%d,%d,%d,%d,%d);",
|
::snprintf(m_temp, sizeof(m_temp), "BOXF(%d,%d,%d,%d,%d);",
|
||||||
0, 0, X_WIDTH - 1, Y_WIDTH - 1, BG_COLOUR);
|
0, 0, X_WIDTH - 1, Y_WIDTH - 1, BG_COLOUR);
|
||||||
m_serial->write((unsigned char*)m_temp, ::strlen(m_temp));
|
m_serial->write((unsigned char*)m_temp, (unsigned int)::strlen(m_temp));
|
||||||
|
|
||||||
// mode line
|
// mode line
|
||||||
::snprintf(m_temp, sizeof(m_temp), "DCV%d(%d,%d,'%s',%d);",
|
::snprintf(m_temp, sizeof(m_temp), "DCV%d(%d,%d,'%s',%d);",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2016,2020,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2006-2016,2020,2024,2025 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
|
||||||
|
|
@ -119,7 +119,7 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
|
||||||
if (addr1.ss_family != addr2.ss_family)
|
if (addr1.ss_family != addr2.ss_family)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (type == IMT_ADDRESS_AND_PORT) {
|
if (type == IPMATCHTYPE::IMT_ADDREAND_PORT) {
|
||||||
switch (addr1.ss_family) {
|
switch (addr1.ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
struct sockaddr_in *in_1, *in_2;
|
struct sockaddr_in *in_1, *in_2;
|
||||||
|
|
@ -134,7 +134,7 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (type == IMT_ADDRESS_ONLY) {
|
} else if (type == IPMATCHTYPE::IMT_ADDREONLY) {
|
||||||
switch (addr1.ss_family) {
|
switch (addr1.ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
struct sockaddr_in *in_1, *in_2;
|
struct sockaddr_in *in_1, *in_2;
|
||||||
|
|
|
||||||
10
UDPSocket.h
10
UDPSocket.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024 by Jonathan Naylor G4KLX
|
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024.2025 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
|
||||||
|
|
@ -36,9 +36,9 @@
|
||||||
#include <Winsock2.h>
|
#include <Winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum IPMATCHTYPE {
|
enum class IPMATCHTYPE {
|
||||||
IMT_ADDRESS_AND_PORT,
|
IMT_ADDREAND_PORT,
|
||||||
IMT_ADDRESS_ONLY
|
IMT_ADDREONLY
|
||||||
};
|
};
|
||||||
|
|
||||||
class CUDPSocket {
|
class CUDPSocket {
|
||||||
|
|
@ -61,7 +61,7 @@ public:
|
||||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
|
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
|
||||||
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
|
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
|
||||||
|
|
||||||
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
|
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IPMATCHTYPE::IMT_ADDREAND_PORT);
|
||||||
|
|
||||||
static bool isNone(const sockaddr_storage& addr);
|
static bool isNone(const sockaddr_storage& addr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@
|
||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20250312";
|
const char* VERSION = "20250313";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2021 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015-2021,2025 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
|
||||||
|
|
@ -33,8 +33,8 @@ m_duplex(duplex),
|
||||||
m_lowDeviation(lowDeviation),
|
m_lowDeviation(lowDeviation),
|
||||||
m_remoteGateway(remoteGateway),
|
m_remoteGateway(remoteGateway),
|
||||||
m_queue(5000U, "YSF Control"),
|
m_queue(5000U, "YSF Control"),
|
||||||
m_rfState(RS_RF_LISTENING),
|
m_rfState(RPT_RF_STATE::LISTENING),
|
||||||
m_netState(RS_NET_IDLE),
|
m_netState(RPT_NET_STATE::IDLE),
|
||||||
m_rfTimeoutTimer(1000U, timeout),
|
m_rfTimeoutTimer(1000U, timeout),
|
||||||
m_netTimeoutTimer(1000U, timeout),
|
m_netTimeoutTimer(1000U, timeout),
|
||||||
m_packetTimer(1000U, 0U, 200U),
|
m_packetTimer(1000U, 0U, 200U),
|
||||||
|
|
@ -107,7 +107,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::AUDIO)) {
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("YSF, transmission lost from %10.10s to %10.10s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_rfSource, m_rfDest, float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("YSF, transmission lost from %10.10s to %10.10s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_rfSource, m_rfDest, float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
|
|
@ -116,17 +116,17 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_REJECTED) {
|
if ((type == TAG_LOST) && (m_rfState == RPT_RF_STATE::REJECTED)) {
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
m_rfSource = NULL;
|
m_rfSource = NULL;
|
||||||
m_rfDest = NULL;
|
m_rfDest = NULL;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST) {
|
if (type == TAG_LOST) {
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||||
unsigned char dgid = m_lastFICH.getDGId();
|
unsigned char dgid = m_lastFICH.getDGId();
|
||||||
|
|
||||||
if (valid && fi == YSF_FI_HEADER) {
|
if (valid && fi == YSF_FI_HEADER) {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
bool valid = m_rfPayload.processHeaderData(data + 2U);
|
bool valid = m_rfPayload.processHeaderData(data + 2U);
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -232,7 +232,7 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||||
bool ret = checkCallsign(m_rfSource);
|
bool ret = checkCallsign(m_rfSource);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +247,7 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 1U;
|
m_rfBits = 1U;
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
|
|
@ -286,13 +286,13 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (valid && fi == YSF_FI_TERMINATOR) {
|
} else if (valid && (fi == YSF_FI_TERMINATOR)) {
|
||||||
if (m_rfState == RS_RF_REJECTED) {
|
if (m_rfState == RPT_RF_STATE::REJECTED) {
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
m_rfSource = NULL;
|
m_rfSource = NULL;
|
||||||
m_rfDest = NULL;
|
m_rfDest = NULL;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
} else if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
m_rfPayload.processHeaderData(data + 2U);
|
m_rfPayload.processHeaderData(data + 2U);
|
||||||
|
|
||||||
CSync::addYSFSync(data + 2U);
|
CSync::addYSFSync(data + 2U);
|
||||||
|
|
@ -325,7 +325,7 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
// If valid is false, update the m_lastFICH for this transmission
|
// If valid is false, update the m_lastFICH for this transmission
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
// XXX Check these values
|
// XXX Check these values
|
||||||
|
|
@ -390,7 +390,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
unsigned char dgid = m_lastFICH.getDGId();
|
unsigned char dgid = m_lastFICH.getDGId();
|
||||||
|
|
||||||
if (valid && fi == YSF_FI_HEADER) {
|
if (valid && fi == YSF_FI_HEADER) {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
bool valid = m_rfPayload.processHeaderData(data + 2U);
|
bool valid = m_rfPayload.processHeaderData(data + 2U);
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -401,7 +401,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
bool ret = checkCallsign(m_rfSource);
|
bool ret = checkCallsign(m_rfSource);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -416,7 +416,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 1U;
|
m_rfBits = 1U;
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
|
|
@ -455,13 +455,13 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (valid && fi == YSF_FI_TERMINATOR) {
|
} else if (valid && (fi == YSF_FI_TERMINATOR)) {
|
||||||
if (m_rfState == RS_RF_REJECTED) {
|
if (m_rfState == RPT_RF_STATE::REJECTED) {
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
m_rfSource = NULL;
|
m_rfSource = NULL;
|
||||||
m_rfDest = NULL;
|
m_rfDest = NULL;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
} else if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
m_rfPayload.processHeaderData(data + 2U);
|
m_rfPayload.processHeaderData(data + 2U);
|
||||||
|
|
||||||
CSync::addYSFSync(data + 2U);
|
CSync::addYSFSync(data + 2U);
|
||||||
|
|
@ -494,7 +494,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if (m_rfState == RPT_RF_STATE::AUDIO) {
|
||||||
// If valid is false, update the m_lastFICH for this transmission
|
// If valid is false, update the m_lastFICH for this transmission
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
unsigned char ft = m_lastFICH.getFT();
|
unsigned char ft = m_lastFICH.getFT();
|
||||||
|
|
@ -560,7 +560,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
m_display->writeFusionRSSI(m_rssi);
|
m_display->writeFusionRSSI(m_rssi);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (valid && m_rfState == RS_RF_LISTENING) {
|
} else if (valid && (m_rfState == RPT_RF_STATE::LISTENING)) {
|
||||||
// Only use clean frames for late entry.
|
// Only use clean frames for late entry.
|
||||||
unsigned char fn = m_lastFICH.getFN();
|
unsigned char fn = m_lastFICH.getFN();
|
||||||
unsigned char dt = m_lastFICH.getDT();
|
unsigned char dt = m_lastFICH.getDT();
|
||||||
|
|
@ -597,7 +597,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
bool ret = checkCallsign(m_rfSource);
|
bool ret = checkCallsign(m_rfSource);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -606,7 +606,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 1U;
|
m_rfBits = 1U;
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RPT_RF_STATE::AUDIO;
|
||||||
|
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
|
|
@ -692,7 +692,7 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data)
|
||||||
unsigned char dgid = m_lastFICH.getDGId();
|
unsigned char dgid = m_lastFICH.getDGId();
|
||||||
|
|
||||||
if (valid && fi == YSF_FI_HEADER) {
|
if (valid && fi == YSF_FI_HEADER) {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RPT_RF_STATE::LISTENING) {
|
||||||
valid = m_rfPayload.processHeaderData(data + 2U);
|
valid = m_rfPayload.processHeaderData(data + 2U);
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -703,7 +703,7 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data)
|
||||||
bool ret = checkCallsign(m_rfSource);
|
bool ret = checkCallsign(m_rfSource);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
LogMessage("YSF, invalid access attempt from %10.10s to DG-ID %u", m_rfSource, dgid);
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RPT_RF_STATE::REJECTED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -715,7 +715,7 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data)
|
||||||
m_rfDest = m_rfPayload.getDest();
|
m_rfDest = m_rfPayload.getDest();
|
||||||
|
|
||||||
m_rfFrames = 0U;
|
m_rfFrames = 0U;
|
||||||
m_rfState = RS_RF_DATA;
|
m_rfState = RPT_RF_STATE::DATA;
|
||||||
|
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
|
|
@ -754,12 +754,12 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (valid && fi == YSF_FI_TERMINATOR) {
|
} else if (valid && fi == YSF_FI_TERMINATOR) {
|
||||||
if (m_rfState == RS_RF_REJECTED) {
|
if (m_rfState == RPT_RF_STATE::REJECTED) {
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
m_rfSource = NULL;
|
m_rfSource = NULL;
|
||||||
m_rfDest = NULL;
|
m_rfDest = NULL;
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
} else if (m_rfState == RS_RF_DATA) {
|
} else if (m_rfState == RPT_RF_STATE::DATA) {
|
||||||
m_rfPayload.processHeaderData(data + 2U);
|
m_rfPayload.processHeaderData(data + 2U);
|
||||||
|
|
||||||
CSync::addYSFSync(data + 2U);
|
CSync::addYSFSync(data + 2U);
|
||||||
|
|
@ -792,7 +792,7 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data)
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_rfState == RS_RF_DATA) {
|
if (m_rfState == RPT_RF_STATE::DATA) {
|
||||||
// If valid is false, update the m_lastFICH for this transmission
|
// If valid is false, update the m_lastFICH for this transmission
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
unsigned char ft = m_lastFICH.getFT();
|
unsigned char ft = m_lastFICH.getFT();
|
||||||
|
|
@ -857,7 +857,7 @@ unsigned int CYSFControl::readModem(unsigned char* data)
|
||||||
|
|
||||||
void CYSFControl::writeEndRF()
|
void CYSFControl::writeEndRF()
|
||||||
{
|
{
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
|
|
@ -866,7 +866,7 @@ void CYSFControl::writeEndRF()
|
||||||
m_rfSource = NULL;
|
m_rfSource = NULL;
|
||||||
m_rfDest = NULL;
|
m_rfDest = NULL;
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RPT_NET_STATE::IDLE) {
|
||||||
m_display->clearFusion();
|
m_display->clearFusion();
|
||||||
|
|
||||||
if (m_network != NULL)
|
if (m_network != NULL)
|
||||||
|
|
@ -880,7 +880,7 @@ void CYSFControl::writeEndRF()
|
||||||
|
|
||||||
void CYSFControl::writeEndNet()
|
void CYSFControl::writeEndNet()
|
||||||
{
|
{
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_netTimeoutTimer.stop();
|
m_netTimeoutTimer.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
|
|
@ -904,7 +904,7 @@ void CYSFControl::writeNetwork()
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
if ((m_rfState != RPT_RF_STATE::LISTENING) && (m_netState == RPT_NET_STATE::IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
@ -937,7 +937,7 @@ void CYSFControl::writeNetwork()
|
||||||
m_netPayload.reset();
|
m_netPayload.reset();
|
||||||
m_packetTimer.start();
|
m_packetTimer.start();
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RPT_NET_STATE::AUDIO;
|
||||||
m_netFrames = 0U;
|
m_netFrames = 0U;
|
||||||
m_netLost = 0U;
|
m_netLost = 0U;
|
||||||
m_netErrs = 0U;
|
m_netErrs = 0U;
|
||||||
|
|
@ -1060,7 +1060,7 @@ void CYSFControl::clock(unsigned int ms)
|
||||||
m_rfTimeoutTimer.clock(ms);
|
m_rfTimeoutTimer.clock(ms);
|
||||||
m_netTimeoutTimer.clock(ms);
|
m_netTimeoutTimer.clock(ms);
|
||||||
|
|
||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RPT_NET_STATE::AUDIO) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
|
|
@ -1074,7 +1074,7 @@ void CYSFControl::writeQueueRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_netState != RS_NET_IDLE)
|
if (m_netState != RPT_NET_STATE::IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
|
@ -1197,7 +1197,7 @@ void CYSFControl::processNetCallsigns(const unsigned char* data, unsigned char d
|
||||||
|
|
||||||
bool CYSFControl::isBusy() const
|
bool CYSFControl::isBusy() const
|
||||||
{
|
{
|
||||||
return m_rfState != RS_RF_LISTENING || m_netState != RS_NET_IDLE;
|
return (m_rfState != RPT_RF_STATE::LISTENING) || (m_netState != RPT_NET_STATE::IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CYSFControl::enable(bool enabled)
|
void CYSFControl::enable(bool enabled)
|
||||||
|
|
@ -1206,7 +1206,7 @@ void CYSFControl::enable(bool enabled)
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
|
|
||||||
// Reset the RF section
|
// Reset the RF section
|
||||||
m_rfState = RS_RF_LISTENING;
|
m_rfState = RPT_RF_STATE::LISTENING;
|
||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
m_rfPayload.reset();
|
m_rfPayload.reset();
|
||||||
|
|
@ -1216,7 +1216,7 @@ void CYSFControl::enable(bool enabled)
|
||||||
m_rfDest = NULL;
|
m_rfDest = NULL;
|
||||||
|
|
||||||
// Reset the networking section
|
// Reset the networking section
|
||||||
m_netState = RS_NET_IDLE;
|
m_netState = RPT_NET_STATE::IDLE;
|
||||||
|
|
||||||
m_netTimeoutTimer.stop();
|
m_netTimeoutTimer.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue