Merge remote-tracking branch 'g4klx/master'
This commit is contained in:
commit
bafa100e66
110 changed files with 20544 additions and 1430 deletions
290
Conf.cpp
290
Conf.cpp
|
@ -55,10 +55,9 @@ enum SECTION {
|
|||
CConf::CConf(const std::string& file) :
|
||||
m_file(file),
|
||||
m_callsign(),
|
||||
m_id(0U),
|
||||
m_timeout(120U),
|
||||
m_duplex(true),
|
||||
m_rfModeHang(10U),
|
||||
m_netModeHang(3U),
|
||||
m_display(),
|
||||
m_daemon(false),
|
||||
m_rxFrequency(0U),
|
||||
|
@ -85,12 +84,16 @@ m_modemTXInvert(false),
|
|||
m_modemPTTInvert(false),
|
||||
m_modemTXDelay(100U),
|
||||
m_modemDMRDelay(0U),
|
||||
m_modemRXLevel(50U),
|
||||
m_modemCWIdTXLevel(50U),
|
||||
m_modemDStarTXLevel(50U),
|
||||
m_modemDMRTXLevel(50U),
|
||||
m_modemYSFTXLevel(50U),
|
||||
m_modemP25TXLevel(50U),
|
||||
m_modemTXOffset(0),
|
||||
m_modemRXOffset(0),
|
||||
m_modemRXDCOffset(0),
|
||||
m_modemTXDCOffset(0),
|
||||
m_modemRXLevel(50.0F),
|
||||
m_modemCWIdTXLevel(50.0F),
|
||||
m_modemDStarTXLevel(50.0F),
|
||||
m_modemDMRTXLevel(50.0F),
|
||||
m_modemYSFTXLevel(50.0F),
|
||||
m_modemP25TXLevel(50.0F),
|
||||
m_modemRSSIMappingFile(),
|
||||
m_modemTrace(false),
|
||||
m_modemDebug(false),
|
||||
|
@ -100,7 +103,11 @@ m_dstarEnabled(false),
|
|||
m_dstarModule("C"),
|
||||
m_dstarSelfOnly(false),
|
||||
m_dstarBlackList(),
|
||||
m_dstarAckReply(true),
|
||||
m_dstarAckTime(750U),
|
||||
m_dstarErrorReply(true),
|
||||
m_dstarRemoteGateway(false),
|
||||
m_dstarModeHang(10U),
|
||||
m_dmrEnabled(false),
|
||||
m_dmrBeacons(false),
|
||||
m_dmrId(0U),
|
||||
|
@ -115,15 +122,26 @@ m_dmrSlot1TGWhiteList(),
|
|||
m_dmrSlot2TGWhiteList(),
|
||||
m_dmrCallHang(3U),
|
||||
m_dmrTXHang(4U),
|
||||
m_dmrModeHang(10U),
|
||||
m_fusionEnabled(false),
|
||||
m_fusionLowDeviation(false),
|
||||
m_fusionRemoteGateway(false),
|
||||
m_fusionSelfOnly(false),
|
||||
m_fusionSQLEnabled(false),
|
||||
m_fusionSQL(0U),
|
||||
m_fusionModeHang(10U),
|
||||
m_p25Enabled(false),
|
||||
m_p25Id(0U),
|
||||
m_p25NAC(0x293U),
|
||||
m_p25SelfOnly(false),
|
||||
m_p25OverrideUID(false),
|
||||
m_p25RemoteGateway(false),
|
||||
m_p25ModeHang(10U),
|
||||
m_dstarNetworkEnabled(false),
|
||||
m_dstarGatewayAddress(),
|
||||
m_dstarGatewayPort(0U),
|
||||
m_dstarLocalPort(0U),
|
||||
m_dstarNetworkModeHang(3U),
|
||||
m_dstarNetworkDebug(false),
|
||||
m_dmrNetworkEnabled(false),
|
||||
m_dmrNetworkAddress(),
|
||||
|
@ -135,18 +153,20 @@ m_dmrNetworkDebug(false),
|
|||
m_dmrNetworkJitter(300U),
|
||||
m_dmrNetworkSlot1(true),
|
||||
m_dmrNetworkSlot2(true),
|
||||
m_dmrNetworkModeHang(3U),
|
||||
m_fusionNetworkEnabled(false),
|
||||
m_fusionNetworkMyAddress(),
|
||||
m_fusionNetworkMyPort(0U),
|
||||
m_fusionNetworkGwyAddress(),
|
||||
m_fusionNetworkGwyPort(0U),
|
||||
m_fusionNetworkGatewayAddress(),
|
||||
m_fusionNetworkGatewayPort(0U),
|
||||
m_fusionNetworkModeHang(3U),
|
||||
m_fusionNetworkDebug(false),
|
||||
m_p25NetworkEnabled(false),
|
||||
m_p25GatewayAddress(),
|
||||
m_p25GatewayPort(0U),
|
||||
m_p25LocalPort(0U),
|
||||
m_p25NetworkModeHang(3U),
|
||||
m_p25NetworkDebug(false),
|
||||
m_p25OverrideUID(false),
|
||||
m_tftSerialPort("/dev/ttyAMA0"),
|
||||
m_tftSerialBrightness(50U),
|
||||
m_hd44780Rows(2U),
|
||||
|
@ -164,9 +184,11 @@ m_nextionBrightness(50U),
|
|||
m_nextionDisplayClock(false),
|
||||
m_nextionUTC(false),
|
||||
m_nextionIdleBrightness(20U),
|
||||
m_nextionScreenLayout(0U),
|
||||
m_oledType(3U),
|
||||
m_oledBrightness(0U),
|
||||
m_oledInvert(false),
|
||||
m_oledScroll(false),
|
||||
m_lcdprocAddress(),
|
||||
m_lcdprocPort(0U),
|
||||
m_lcdprocLocalPort(0U),
|
||||
|
@ -255,16 +277,19 @@ bool CConf::read()
|
|||
for (unsigned int i = 0U; value[i] != 0; i++)
|
||||
value[i] = ::toupper(value[i]);
|
||||
m_cwIdCallsign = m_callsign = value;
|
||||
} else if (::strcmp(key, "Timeout") == 0)
|
||||
} else if (::strcmp(key, "Id") == 0)
|
||||
m_id = m_p25Id = m_dmrId = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Timeout") == 0)
|
||||
m_timeout = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Duplex") == 0)
|
||||
m_duplex = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_rfModeHang = m_netModeHang = (unsigned int)::atoi(value);
|
||||
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang =
|
||||
m_dstarModeHang = m_dmrModeHang = m_fusionModeHang = m_p25ModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "RFModeHang") == 0)
|
||||
m_rfModeHang = (unsigned int)::atoi(value);
|
||||
m_dstarModeHang = m_dmrModeHang = m_fusionModeHang = m_p25ModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "NetModeHang") == 0)
|
||||
m_netModeHang = (unsigned int)::atoi(value);
|
||||
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Display") == 0)
|
||||
m_display = value;
|
||||
else if (::strcmp(key, "Daemon") == 0)
|
||||
|
@ -326,20 +351,28 @@ bool CConf::read()
|
|||
m_modemTXDelay = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "DMRDelay") == 0)
|
||||
m_modemDMRDelay = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "RXOffset") == 0)
|
||||
m_modemRXOffset = ::atoi(value);
|
||||
else if (::strcmp(key, "TXOffset") == 0)
|
||||
m_modemTXOffset = ::atoi(value);
|
||||
else if (::strcmp(key, "RXDCOffset") == 0)
|
||||
m_modemRXDCOffset = ::atoi(value);
|
||||
else if (::strcmp(key, "TXDCOffset") == 0)
|
||||
m_modemTXDCOffset = ::atoi(value);
|
||||
else if (::strcmp(key, "RXLevel") == 0)
|
||||
m_modemRXLevel = (unsigned int)::atoi(value);
|
||||
m_modemRXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "TXLevel") == 0)
|
||||
m_modemCWIdTXLevel = m_modemDStarTXLevel = m_modemDMRTXLevel = m_modemYSFTXLevel = m_modemP25TXLevel = (unsigned int)::atoi(value);
|
||||
m_modemCWIdTXLevel = m_modemDStarTXLevel = m_modemDMRTXLevel = m_modemYSFTXLevel = m_modemP25TXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "CWIdTXLevel") == 0)
|
||||
m_modemCWIdTXLevel = (unsigned int)::atoi(value);
|
||||
m_modemCWIdTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "D-StarTXLevel") == 0)
|
||||
m_modemDStarTXLevel = (unsigned int)::atoi(value);
|
||||
m_modemDStarTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "DMRTXLevel") == 0)
|
||||
m_modemDMRTXLevel = (unsigned int)::atoi(value);
|
||||
m_modemDMRTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "YSFTXLevel") == 0)
|
||||
m_modemYSFTXLevel = (unsigned int)::atoi(value);
|
||||
m_modemYSFTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "P25TXLevel") == 0)
|
||||
m_modemP25TXLevel = (unsigned int)::atoi(value);
|
||||
m_modemP25TXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "RSSIMappingFile") == 0)
|
||||
m_modemRSSIMappingFile = value;
|
||||
else if (::strcmp(key, "Trace") == 0)
|
||||
|
@ -373,8 +406,16 @@ bool CConf::read()
|
|||
}
|
||||
p = ::strtok(NULL, ",\r\n");
|
||||
}
|
||||
} else if (::strcmp(key, "ErrorReply") == 0)
|
||||
} else if (::strcmp(key, "AckReply") == 0)
|
||||
m_dstarAckReply = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "AckTime") == 0)
|
||||
m_dstarAckTime = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ErrorReply") == 0)
|
||||
m_dstarErrorReply = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "RemoteGateway") == 0)
|
||||
m_dstarRemoteGateway = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_dstarModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_DMR) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_dmrEnabled = ::atoi(value) == 1;
|
||||
|
@ -434,20 +475,37 @@ bool CConf::read()
|
|||
m_dmrTXHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "CallHang") == 0)
|
||||
m_dmrCallHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_dmrModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_FUSION) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_fusionEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "LowDeviation") == 0)
|
||||
m_fusionLowDeviation = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "RemoteGateway") == 0)
|
||||
else if (::strcmp(key, "DSQ") == 0) {
|
||||
m_fusionSQLEnabled = true;
|
||||
m_fusionSQL = (unsigned int)::atoi(value);
|
||||
} else if (::strcmp(key, "RemoteGateway") == 0)
|
||||
m_fusionRemoteGateway = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "SelfOnly") == 0)
|
||||
m_fusionSelfOnly = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_fusionModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_P25) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_p25Enabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Id") == 0)
|
||||
m_p25Id = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "NAC") == 0)
|
||||
m_p25NAC = (unsigned int)::strtoul(value, NULL, 16);
|
||||
else if (::strcmp(key, "OverrideUIDCheck") == 0)
|
||||
m_p25OverrideUID = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "SelfOnly") == 0)
|
||||
m_p25SelfOnly = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "RemoteGateway") == 0)
|
||||
m_p25RemoteGateway = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_p25ModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_DSTAR_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_dstarNetworkEnabled = ::atoi(value) == 1;
|
||||
|
@ -457,6 +515,8 @@ bool CConf::read()
|
|||
m_dstarGatewayPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "LocalPort") == 0)
|
||||
m_dstarLocalPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_dstarNetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_dstarNetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_DMR_NETWORK) {
|
||||
|
@ -480,6 +540,8 @@ bool CConf::read()
|
|||
m_dmrNetworkSlot1 = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Slot2") == 0)
|
||||
m_dmrNetworkSlot2 = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_dmrNetworkModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_FUSION_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_fusionNetworkEnabled = ::atoi(value) == 1;
|
||||
|
@ -487,10 +549,12 @@ bool CConf::read()
|
|||
m_fusionNetworkMyAddress = value;
|
||||
else if (::strcmp(key, "LocalPort") == 0)
|
||||
m_fusionNetworkMyPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "GwyAddress") == 0)
|
||||
m_fusionNetworkGwyAddress = value;
|
||||
else if (::strcmp(key, "GwyPort") == 0)
|
||||
m_fusionNetworkGwyPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "GatewayAddress") == 0)
|
||||
m_fusionNetworkGatewayAddress = value;
|
||||
else if (::strcmp(key, "GatewayPort") == 0)
|
||||
m_fusionNetworkGatewayPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_fusionNetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_fusionNetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_P25_NETWORK) {
|
||||
|
@ -502,6 +566,8 @@ bool CConf::read()
|
|||
m_p25GatewayPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "LocalPort") == 0)
|
||||
m_p25LocalPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_p25NetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_p25NetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_TFTSERIAL) {
|
||||
|
@ -547,6 +613,8 @@ bool CConf::read()
|
|||
m_nextionUTC = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "IdleBrightness") == 0)
|
||||
m_nextionIdleBrightness = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ScreenLayout") == 0)
|
||||
m_nextionScreenLayout = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_OLED) {
|
||||
if (::strcmp(key, "Type") == 0)
|
||||
m_oledType = (unsigned char)::atoi(value);
|
||||
|
@ -554,6 +622,8 @@ bool CConf::read()
|
|||
m_oledBrightness = (unsigned char)::atoi(value);
|
||||
else if (::strcmp(key, "Invert") == 0)
|
||||
m_oledInvert = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Scroll") == 0)
|
||||
m_oledScroll = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_LCDPROC) {
|
||||
if (::strcmp(key, "Address") == 0)
|
||||
m_lcdprocAddress = value;
|
||||
|
@ -580,6 +650,11 @@ std::string CConf::getCallsign() const
|
|||
return m_callsign;
|
||||
}
|
||||
|
||||
unsigned int CConf::getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
unsigned int CConf::getTimeout() const
|
||||
{
|
||||
return m_timeout;
|
||||
|
@ -590,16 +665,6 @@ bool CConf::getDuplex() const
|
|||
return m_duplex;
|
||||
}
|
||||
|
||||
unsigned int CConf::getRFModeHang() const
|
||||
{
|
||||
return m_rfModeHang;
|
||||
}
|
||||
|
||||
unsigned int CConf::getNetModeHang() const
|
||||
{
|
||||
return m_netModeHang;
|
||||
}
|
||||
|
||||
std::string CConf::getDisplay() const
|
||||
{
|
||||
return m_display;
|
||||
|
@ -610,12 +675,12 @@ bool CConf::getDaemon() const
|
|||
return m_daemon;
|
||||
}
|
||||
|
||||
unsigned int CConf::getRxFrequency() const
|
||||
unsigned int CConf::getRXFrequency() const
|
||||
{
|
||||
return m_rxFrequency;
|
||||
}
|
||||
|
||||
unsigned int CConf::getTxFrequency() const
|
||||
unsigned int CConf::getTXFrequency() const
|
||||
{
|
||||
return m_txFrequency;
|
||||
}
|
||||
|
@ -730,32 +795,52 @@ unsigned int CConf::getModemDMRDelay() const
|
|||
return m_modemDMRDelay;
|
||||
}
|
||||
|
||||
unsigned int CConf::getModemRXLevel() const
|
||||
int CConf::getModemRXOffset() const
|
||||
{
|
||||
return m_modemRXOffset;
|
||||
}
|
||||
|
||||
int CConf::getModemTXOffset() const
|
||||
{
|
||||
return m_modemTXOffset;
|
||||
}
|
||||
|
||||
int CConf::getModemRXDCOffset() const
|
||||
{
|
||||
return m_modemRXDCOffset;
|
||||
}
|
||||
|
||||
int CConf::getModemTXDCOffset() const
|
||||
{
|
||||
return m_modemTXDCOffset;
|
||||
}
|
||||
|
||||
float CConf::getModemRXLevel() const
|
||||
{
|
||||
return m_modemRXLevel;
|
||||
}
|
||||
|
||||
unsigned int CConf::getModemCWIdTXLevel() const
|
||||
float CConf::getModemCWIdTXLevel() const
|
||||
{
|
||||
return m_modemCWIdTXLevel;
|
||||
}
|
||||
|
||||
unsigned int CConf::getModemDStarTXLevel() const
|
||||
float CConf::getModemDStarTXLevel() const
|
||||
{
|
||||
return m_modemDStarTXLevel;
|
||||
}
|
||||
|
||||
unsigned int CConf::getModemDMRTXLevel() const
|
||||
float CConf::getModemDMRTXLevel() const
|
||||
{
|
||||
return m_modemDMRTXLevel;
|
||||
}
|
||||
|
||||
unsigned int CConf::getModemYSFTXLevel() const
|
||||
float CConf::getModemYSFTXLevel() const
|
||||
{
|
||||
return m_modemYSFTXLevel;
|
||||
}
|
||||
|
||||
unsigned int CConf::getModemP25TXLevel() const
|
||||
float CConf::getModemP25TXLevel() const
|
||||
{
|
||||
return m_modemP25TXLevel;
|
||||
}
|
||||
|
@ -805,11 +890,31 @@ std::vector<std::string> CConf::getDStarBlackList() const
|
|||
return m_dstarBlackList;
|
||||
}
|
||||
|
||||
bool CConf::getDStarAckReply() const
|
||||
{
|
||||
return m_dstarAckReply;
|
||||
}
|
||||
|
||||
unsigned int CConf::getDStarAckTime() const
|
||||
{
|
||||
return m_dstarAckTime;
|
||||
}
|
||||
|
||||
bool CConf::getDStarErrorReply() const
|
||||
{
|
||||
return m_dstarErrorReply;
|
||||
}
|
||||
|
||||
bool CConf::getDStarRemoteGateway() const
|
||||
{
|
||||
return m_dstarRemoteGateway;
|
||||
}
|
||||
|
||||
unsigned int CConf::getDStarModeHang() const
|
||||
{
|
||||
return m_dstarModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getDMREnabled() const
|
||||
{
|
||||
return m_dmrEnabled;
|
||||
|
@ -880,6 +985,11 @@ unsigned int CConf::getDMRTXHang() const
|
|||
return m_dmrTXHang;
|
||||
}
|
||||
|
||||
unsigned int CConf::getDMRModeHang() const
|
||||
{
|
||||
return m_dmrModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getFusionEnabled() const
|
||||
{
|
||||
return m_fusionEnabled;
|
||||
|
@ -895,16 +1005,61 @@ bool CConf::getFusionRemoteGateway() const
|
|||
return m_fusionRemoteGateway;
|
||||
}
|
||||
|
||||
bool CConf::getFusionSelfOnly() const
|
||||
{
|
||||
return m_fusionSelfOnly;
|
||||
}
|
||||
|
||||
bool CConf::getFusionSQLEnabled() const
|
||||
{
|
||||
return m_fusionSQLEnabled;
|
||||
}
|
||||
|
||||
unsigned char CConf::getFusionSQL() const
|
||||
{
|
||||
return m_fusionSQL;
|
||||
}
|
||||
|
||||
unsigned int CConf::getFusionModeHang() const
|
||||
{
|
||||
return m_fusionModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getP25Enabled() const
|
||||
{
|
||||
return m_p25Enabled;
|
||||
}
|
||||
|
||||
unsigned int CConf::getP25Id() const
|
||||
{
|
||||
return m_p25Id;
|
||||
}
|
||||
|
||||
unsigned int CConf::getP25NAC() const
|
||||
{
|
||||
return m_p25NAC;
|
||||
}
|
||||
|
||||
bool CConf::getP25OverrideUID() const
|
||||
{
|
||||
return m_p25OverrideUID;
|
||||
}
|
||||
|
||||
bool CConf::getP25SelfOnly() const
|
||||
{
|
||||
return m_p25SelfOnly;
|
||||
}
|
||||
|
||||
bool CConf::getP25RemoteGateway() const
|
||||
{
|
||||
return m_p25RemoteGateway;
|
||||
}
|
||||
|
||||
unsigned int CConf::getP25ModeHang() const
|
||||
{
|
||||
return m_p25ModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getDStarNetworkEnabled() const
|
||||
{
|
||||
return m_dstarNetworkEnabled;
|
||||
|
@ -925,6 +1080,11 @@ unsigned int CConf::getDStarLocalPort() const
|
|||
return m_dstarLocalPort;
|
||||
}
|
||||
|
||||
unsigned int CConf::getDStarNetworkModeHang() const
|
||||
{
|
||||
return m_dstarNetworkModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getDStarNetworkDebug() const
|
||||
{
|
||||
return m_dstarNetworkDebug;
|
||||
|
@ -960,6 +1120,11 @@ std::string CConf::getDMRNetworkOptions() const
|
|||
return m_dmrNetworkOptions;
|
||||
}
|
||||
|
||||
unsigned int CConf::getDMRNetworkModeHang() const
|
||||
{
|
||||
return m_dmrNetworkModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getDMRNetworkDebug() const
|
||||
{
|
||||
return m_dmrNetworkDebug;
|
||||
|
@ -995,14 +1160,19 @@ unsigned int CConf::getFusionNetworkMyPort() const
|
|||
return m_fusionNetworkMyPort;
|
||||
}
|
||||
|
||||
std::string CConf::getFusionNetworkGwyAddress() const
|
||||
std::string CConf::getFusionNetworkGatewayAddress() const
|
||||
{
|
||||
return m_fusionNetworkGwyAddress;
|
||||
return m_fusionNetworkGatewayAddress;
|
||||
}
|
||||
|
||||
unsigned int CConf::getFusionNetworkGwyPort() const
|
||||
unsigned int CConf::getFusionNetworkGatewayPort() const
|
||||
{
|
||||
return m_fusionNetworkGwyPort;
|
||||
return m_fusionNetworkGatewayPort;
|
||||
}
|
||||
|
||||
unsigned int CConf::getFusionNetworkModeHang() const
|
||||
{
|
||||
return m_fusionNetworkModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getFusionNetworkDebug() const
|
||||
|
@ -1030,16 +1200,16 @@ unsigned int CConf::getP25LocalPort() const
|
|||
return m_p25LocalPort;
|
||||
}
|
||||
|
||||
unsigned int CConf::getP25NetworkModeHang() const
|
||||
{
|
||||
return m_p25NetworkModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getP25NetworkDebug() const
|
||||
{
|
||||
return m_p25NetworkDebug;
|
||||
}
|
||||
|
||||
bool CConf::getP25OverrideUID() const
|
||||
{
|
||||
return m_p25OverrideUID;
|
||||
}
|
||||
|
||||
std::string CConf::getTFTSerialPort() const
|
||||
{
|
||||
return m_tftSerialPort;
|
||||
|
@ -1125,6 +1295,11 @@ unsigned int CConf::getNextionIdleBrightness() const
|
|||
return m_nextionIdleBrightness;
|
||||
}
|
||||
|
||||
unsigned int CConf::getNextionScreenLayout() const
|
||||
{
|
||||
return m_nextionScreenLayout;
|
||||
}
|
||||
|
||||
unsigned char CConf::getOLEDType() const
|
||||
{
|
||||
return m_oledType;
|
||||
|
@ -1140,6 +1315,11 @@ bool CConf::getOLEDInvert() const
|
|||
return m_oledInvert;
|
||||
}
|
||||
|
||||
bool CConf::getOLEDScroll() const
|
||||
{
|
||||
return m_oledScroll;
|
||||
}
|
||||
|
||||
std::string CConf::getLCDprocAddress() const
|
||||
{
|
||||
return m_lcdprocAddress;
|
||||
|
|
92
Conf.h
92
Conf.h
|
@ -32,16 +32,15 @@ public:
|
|||
|
||||
// The General section
|
||||
std::string getCallsign() const;
|
||||
unsigned int getId() const;
|
||||
unsigned int getTimeout() const;
|
||||
bool getDuplex() const;
|
||||
unsigned int getRFModeHang() const;
|
||||
unsigned int getNetModeHang() const;
|
||||
std::string getDisplay() const;
|
||||
bool getDaemon() const;
|
||||
|
||||
// The Info section
|
||||
unsigned int getRxFrequency() const;
|
||||
unsigned int getTxFrequency() const;
|
||||
unsigned int getRXFrequency() const;
|
||||
unsigned int getTXFrequency() const;
|
||||
unsigned int getPower() const;
|
||||
float getLatitude() const;
|
||||
float getLongitude() const;
|
||||
|
@ -72,12 +71,16 @@ public:
|
|||
bool getModemPTTInvert() const;
|
||||
unsigned int getModemTXDelay() const;
|
||||
unsigned int getModemDMRDelay() const;
|
||||
unsigned int getModemRXLevel() const;
|
||||
unsigned int getModemCWIdTXLevel() const;
|
||||
unsigned int getModemDStarTXLevel() const;
|
||||
unsigned int getModemDMRTXLevel() const;
|
||||
unsigned int getModemYSFTXLevel() const;
|
||||
unsigned int getModemP25TXLevel() const;
|
||||
int getModemTXOffset() const;
|
||||
int getModemRXOffset() const;
|
||||
int getModemRXDCOffset() const;
|
||||
int getModemTXDCOffset() const;
|
||||
float getModemRXLevel() const;
|
||||
float getModemCWIdTXLevel() const;
|
||||
float getModemDStarTXLevel() const;
|
||||
float getModemDMRTXLevel() const;
|
||||
float getModemYSFTXLevel() const;
|
||||
float getModemP25TXLevel() const;
|
||||
std::string getModemRSSIMappingFile() const;
|
||||
bool getModemTrace() const;
|
||||
bool getModemDebug() const;
|
||||
|
@ -91,7 +94,11 @@ public:
|
|||
std::string getDStarModule() const;
|
||||
bool getDStarSelfOnly() const;
|
||||
std::vector<std::string> getDStarBlackList() const;
|
||||
bool getDStarAckReply() const;
|
||||
unsigned int getDStarAckTime() const;
|
||||
bool getDStarErrorReply() const;
|
||||
bool getDStarRemoteGateway() const;
|
||||
unsigned int getDStarModeHang() const;
|
||||
|
||||
// The DMR section
|
||||
bool getDMREnabled() const;
|
||||
|
@ -108,21 +115,32 @@ public:
|
|||
std::vector<unsigned int> getDMRSlot2TGWhiteList() const;
|
||||
unsigned int getDMRCallHang() const;
|
||||
unsigned int getDMRTXHang() const;
|
||||
unsigned int getDMRModeHang() const;
|
||||
|
||||
// The System Fusion section
|
||||
bool getFusionEnabled() const;
|
||||
bool getFusionLowDeviation() const;
|
||||
bool getFusionRemoteGateway() const;
|
||||
bool getFusionSelfOnly() const;
|
||||
bool getFusionSQLEnabled() const;
|
||||
unsigned char getFusionSQL() const;
|
||||
unsigned int getFusionModeHang() const;
|
||||
|
||||
// The P25 section
|
||||
bool getP25Enabled() const;
|
||||
unsigned int getP25Id() const;
|
||||
unsigned int getP25NAC() const;
|
||||
bool getP25SelfOnly() const;
|
||||
bool getP25OverrideUID() const;
|
||||
bool getP25RemoteGateway() const;
|
||||
unsigned int getP25ModeHang() const;
|
||||
|
||||
// The D-Star Network section
|
||||
bool getDStarNetworkEnabled() const;
|
||||
std::string getDStarGatewayAddress() const;
|
||||
unsigned int getDStarGatewayPort() const;
|
||||
unsigned int getDStarLocalPort() const;
|
||||
unsigned int getDStarNetworkModeHang() const;
|
||||
bool getDStarNetworkDebug() const;
|
||||
|
||||
// The DMR Network section
|
||||
|
@ -136,13 +154,15 @@ public:
|
|||
unsigned int getDMRNetworkJitter() const;
|
||||
bool getDMRNetworkSlot1() const;
|
||||
bool getDMRNetworkSlot2() const;
|
||||
unsigned int getDMRNetworkModeHang() const;
|
||||
|
||||
// The System Fusion Network section
|
||||
bool getFusionNetworkEnabled() const;
|
||||
std::string getFusionNetworkMyAddress() const;
|
||||
unsigned int getFusionNetworkMyPort() const;
|
||||
std::string getFusionNetworkGwyAddress() const;
|
||||
unsigned int getFusionNetworkGwyPort() const;
|
||||
std::string getFusionNetworkGatewayAddress() const;
|
||||
unsigned int getFusionNetworkGatewayPort() const;
|
||||
unsigned int getFusionNetworkModeHang() const;
|
||||
bool getFusionNetworkDebug() const;
|
||||
|
||||
// The P25 Network section
|
||||
|
@ -150,8 +170,8 @@ public:
|
|||
std::string getP25GatewayAddress() const;
|
||||
unsigned int getP25GatewayPort() const;
|
||||
unsigned int getP25LocalPort() const;
|
||||
unsigned int getP25NetworkModeHang() const;
|
||||
bool getP25NetworkDebug() const;
|
||||
bool getP25OverrideUID() const;
|
||||
|
||||
// The TFTSERIAL section
|
||||
std::string getTFTSerialPort() const;
|
||||
|
@ -175,11 +195,13 @@ public:
|
|||
bool getNextionDisplayClock() const;
|
||||
bool getNextionUTC() const;
|
||||
unsigned int getNextionIdleBrightness() const;
|
||||
unsigned int getNextionScreenLayout() const;
|
||||
|
||||
// The OLED section
|
||||
unsigned char getOLEDType() const;
|
||||
unsigned char getOLEDBrightness() const;
|
||||
bool getOLEDInvert() const;
|
||||
bool getOLEDScroll() const;
|
||||
|
||||
// The LCDproc section
|
||||
std::string getLCDprocAddress() const;
|
||||
|
@ -192,10 +214,9 @@ public:
|
|||
private:
|
||||
std::string m_file;
|
||||
std::string m_callsign;
|
||||
unsigned int m_id;
|
||||
unsigned int m_timeout;
|
||||
bool m_duplex;
|
||||
unsigned int m_rfModeHang;
|
||||
unsigned int m_netModeHang;
|
||||
std::string m_display;
|
||||
bool m_daemon;
|
||||
|
||||
|
@ -227,12 +248,16 @@ private:
|
|||
bool m_modemPTTInvert;
|
||||
unsigned int m_modemTXDelay;
|
||||
unsigned int m_modemDMRDelay;
|
||||
unsigned int m_modemRXLevel;
|
||||
unsigned int m_modemCWIdTXLevel;
|
||||
unsigned int m_modemDStarTXLevel;
|
||||
unsigned int m_modemDMRTXLevel;
|
||||
unsigned int m_modemYSFTXLevel;
|
||||
unsigned int m_modemP25TXLevel;
|
||||
int m_modemTXOffset;
|
||||
int m_modemRXOffset;
|
||||
int m_modemRXDCOffset;
|
||||
int m_modemTXDCOffset;
|
||||
float m_modemRXLevel;
|
||||
float m_modemCWIdTXLevel;
|
||||
float m_modemDStarTXLevel;
|
||||
float m_modemDMRTXLevel;
|
||||
float m_modemYSFTXLevel;
|
||||
float m_modemP25TXLevel;
|
||||
std::string m_modemRSSIMappingFile;
|
||||
bool m_modemTrace;
|
||||
bool m_modemDebug;
|
||||
|
@ -244,7 +269,11 @@ private:
|
|||
std::string m_dstarModule;
|
||||
bool m_dstarSelfOnly;
|
||||
std::vector<std::string> m_dstarBlackList;
|
||||
bool m_dstarAckReply;
|
||||
unsigned int m_dstarAckTime;
|
||||
bool m_dstarErrorReply;
|
||||
bool m_dstarRemoteGateway;
|
||||
unsigned int m_dstarModeHang;
|
||||
|
||||
bool m_dmrEnabled;
|
||||
bool m_dmrBeacons;
|
||||
|
@ -260,18 +289,29 @@ private:
|
|||
std::vector<unsigned int> m_dmrSlot2TGWhiteList;
|
||||
unsigned int m_dmrCallHang;
|
||||
unsigned int m_dmrTXHang;
|
||||
unsigned int m_dmrModeHang;
|
||||
|
||||
bool m_fusionEnabled;
|
||||
bool m_fusionLowDeviation;
|
||||
bool m_fusionRemoteGateway;
|
||||
bool m_fusionSelfOnly;
|
||||
bool m_fusionSQLEnabled;
|
||||
unsigned char m_fusionSQL;
|
||||
unsigned int m_fusionModeHang;
|
||||
|
||||
bool m_p25Enabled;
|
||||
unsigned int m_p25Id;
|
||||
unsigned int m_p25NAC;
|
||||
bool m_p25SelfOnly;
|
||||
bool m_p25OverrideUID;
|
||||
bool m_p25RemoteGateway;
|
||||
unsigned int m_p25ModeHang;
|
||||
|
||||
bool m_dstarNetworkEnabled;
|
||||
std::string m_dstarGatewayAddress;
|
||||
unsigned int m_dstarGatewayPort;
|
||||
unsigned int m_dstarLocalPort;
|
||||
unsigned int m_dstarNetworkModeHang;
|
||||
bool m_dstarNetworkDebug;
|
||||
|
||||
bool m_dmrNetworkEnabled;
|
||||
|
@ -284,20 +324,22 @@ private:
|
|||
unsigned int m_dmrNetworkJitter;
|
||||
bool m_dmrNetworkSlot1;
|
||||
bool m_dmrNetworkSlot2;
|
||||
unsigned int m_dmrNetworkModeHang;
|
||||
|
||||
bool m_fusionNetworkEnabled;
|
||||
std::string m_fusionNetworkMyAddress;
|
||||
unsigned int m_fusionNetworkMyPort;
|
||||
std::string m_fusionNetworkGwyAddress;
|
||||
unsigned int m_fusionNetworkGwyPort;
|
||||
std::string m_fusionNetworkGatewayAddress;
|
||||
unsigned int m_fusionNetworkGatewayPort;
|
||||
unsigned int m_fusionNetworkModeHang;
|
||||
bool m_fusionNetworkDebug;
|
||||
|
||||
bool m_p25NetworkEnabled;
|
||||
std::string m_p25GatewayAddress;
|
||||
unsigned int m_p25GatewayPort;
|
||||
unsigned int m_p25LocalPort;
|
||||
unsigned int m_p25NetworkModeHang;
|
||||
bool m_p25NetworkDebug;
|
||||
bool m_p25OverrideUID;
|
||||
|
||||
std::string m_tftSerialPort;
|
||||
unsigned int m_tftSerialBrightness;
|
||||
|
@ -318,10 +360,12 @@ private:
|
|||
bool m_nextionDisplayClock;
|
||||
bool m_nextionUTC;
|
||||
unsigned int m_nextionIdleBrightness;
|
||||
unsigned int m_nextionScreenLayout;
|
||||
|
||||
unsigned char m_oledType;
|
||||
unsigned char m_oledBrightness;
|
||||
bool m_oledInvert;
|
||||
bool m_oledScroll;
|
||||
|
||||
std::string m_lcdprocAddress;
|
||||
unsigned int m_lcdprocPort;
|
||||
|
|
|
@ -48,8 +48,14 @@ void CDMRAccessControl::init(const std::vector<unsigned int>& blacklist, const s
|
|||
|
||||
bool CDMRAccessControl::validateSrcId(unsigned int id)
|
||||
{
|
||||
if (m_selfOnly)
|
||||
if (m_selfOnly) {
|
||||
if (m_id > 99999999U) // Check that the Config DMR-ID is bigger than 8 digits
|
||||
return id == m_id / 100U; // Does RF ID match Config ID / 100
|
||||
else if (m_id > 9999999U) // Check that the Config DMR-ID is bigger than 7 digits
|
||||
return id == m_id / 10U; // Does RF ID match Config ID / 10
|
||||
else
|
||||
return id == m_id;
|
||||
}
|
||||
|
||||
if (std::find(m_blackList.begin(), m_blackList.end(), id) != m_blackList.end())
|
||||
return false;
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#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, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter) :
|
||||
m_id(id),
|
||||
m_colorCode(colorCode),
|
||||
m_modem(modem),
|
||||
m_network(network),
|
||||
|
@ -64,25 +63,17 @@ bool CDMRControl::processWakeup(const unsigned char* data)
|
|||
return false;
|
||||
|
||||
unsigned int srcId = csbk.getSrcId();
|
||||
unsigned int bsId = csbk.getBSId();
|
||||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
|
||||
bool ret = CDMRAccessControl::validateSrcId(srcId);
|
||||
if (!ret) {
|
||||
LogMessage("Invalid CSBK BS_Dwn_Act received from %s", src.c_str());
|
||||
LogMessage("Invalid Downlink Activate received from %s", src.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bsId == 0xFFFFFFU) {
|
||||
LogMessage("CSBK BS_Dwn_Act for ANY received from %s", src.c_str());
|
||||
return true;
|
||||
} else if (bsId == m_id) {
|
||||
LogMessage("CSBK BS_Dwn_Act for %u received from %s", bsId, src.c_str());
|
||||
return true;
|
||||
}
|
||||
LogMessage("Downlink Activate received from %s", src.c_str());
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDMRControl::writeModemSlot1(unsigned char *data, unsigned int len)
|
||||
|
|
|
@ -45,7 +45,6 @@ public:
|
|||
void clock();
|
||||
|
||||
private:
|
||||
unsigned int m_id;
|
||||
unsigned int m_colorCode;
|
||||
CModem* m_modem;
|
||||
CDMRNetwork* m_network;
|
||||
|
|
15
DMRData.cpp
15
DMRData.cpp
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -29,6 +29,7 @@ m_dstId(data.m_dstId),
|
|||
m_flco(data.m_flco),
|
||||
m_dataType(data.m_dataType),
|
||||
m_seqNo(data.m_seqNo),
|
||||
m_missing(data.m_missing),
|
||||
m_n(data.m_n),
|
||||
m_ber(data.m_ber),
|
||||
m_rssi(data.m_rssi)
|
||||
|
@ -45,6 +46,7 @@ m_dstId(0U),
|
|||
m_flco(FLCO_GROUP),
|
||||
m_dataType(0U),
|
||||
m_seqNo(0U),
|
||||
m_missing(false),
|
||||
m_n(0U),
|
||||
m_ber(0U),
|
||||
m_rssi(0U)
|
||||
|
@ -68,6 +70,7 @@ CDMRData& CDMRData::operator=(const CDMRData& data)
|
|||
m_flco = data.m_flco;
|
||||
m_dataType = data.m_dataType;
|
||||
m_seqNo = data.m_seqNo;
|
||||
m_missing = data.m_missing;
|
||||
m_n = data.m_n;
|
||||
m_ber = data.m_ber;
|
||||
m_rssi = data.m_rssi;
|
||||
|
@ -138,6 +141,16 @@ void CDMRData::setSeqNo(unsigned char seqNo)
|
|||
m_seqNo = seqNo;
|
||||
}
|
||||
|
||||
bool CDMRData::isMissing() const
|
||||
{
|
||||
return m_missing;
|
||||
}
|
||||
|
||||
void CDMRData::setMissing(bool missing)
|
||||
{
|
||||
m_missing = missing;
|
||||
}
|
||||
|
||||
unsigned char CDMRData::getN() const
|
||||
{
|
||||
return m_n;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor, G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -45,11 +45,14 @@ public:
|
|||
unsigned char getDataType() const;
|
||||
void setDataType(unsigned char dataType);
|
||||
|
||||
bool isMissing() const;
|
||||
void setMissing(bool missing);
|
||||
|
||||
unsigned char getBER() const;
|
||||
void setBER(unsigned char ber);
|
||||
|
||||
unsigned char getRSSI() const;
|
||||
void setRSSI(unsigned char ber);
|
||||
void setRSSI(unsigned char rssi);
|
||||
|
||||
void setData(const unsigned char* buffer);
|
||||
unsigned int getData(unsigned char* buffer) const;
|
||||
|
@ -62,6 +65,7 @@ private:
|
|||
FLCO m_flco;
|
||||
unsigned char m_dataType;
|
||||
unsigned char m_seqNo;
|
||||
bool m_missing;
|
||||
unsigned char m_n;
|
||||
unsigned char m_ber;
|
||||
unsigned char m_rssi;
|
||||
|
|
18007
DMRIds.dat
18007
DMRIds.dat
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -103,6 +103,17 @@ std::string CDMRLookup::find(unsigned int id)
|
|||
return callsign;
|
||||
}
|
||||
|
||||
bool CDMRLookup::exists(unsigned int id)
|
||||
{
|
||||
m_mutex.lock();
|
||||
|
||||
bool found = m_table.count(id) == 1U;
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool CDMRLookup::load()
|
||||
{
|
||||
FILE* fp = ::fopen(m_filename.c_str(), "rt");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
std::string find(unsigned int id);
|
||||
|
||||
bool exists(unsigned int id);
|
||||
|
||||
void stop();
|
||||
|
||||
private:
|
||||
|
|
|
@ -383,7 +383,7 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||
}
|
||||
} else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) {
|
||||
if (m_status == RUNNING) {
|
||||
LogWarning("DMR, The master is restarting, logging back in");
|
||||
LogWarning("DMR, Login to the master has failed, retrying login ...");
|
||||
m_status = WAITING_LOGIN;
|
||||
m_timeoutTimer.start();
|
||||
m_retryTimer.start();
|
||||
|
@ -391,7 +391,7 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||
/* Once the modem death spiral has been prevented in Modem.cpp
|
||||
the Network sometimes times out and reaches here.
|
||||
We want it to reconnect so... */
|
||||
LogError("DMR, Login to the master has failed, retrying ...");
|
||||
LogError("DMR, Login to the master has failed, retrying network ...");
|
||||
close();
|
||||
open();
|
||||
return;
|
||||
|
@ -543,6 +543,9 @@ bool CDMRNetwork::writeConfig()
|
|||
case HWT_DVMEGA:
|
||||
software = "MMDVM_DVMega";
|
||||
break;
|
||||
case HWT_MMDVM_HS:
|
||||
software = "MMDVM_HS";
|
||||
break;
|
||||
default:
|
||||
software = "MMDVM_Unknown";
|
||||
break;
|
||||
|
|
189
DMRSlot.cpp
189
DMRSlot.cpp
|
@ -29,6 +29,7 @@
|
|||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
unsigned int CDMRSlot::m_colorCode = 0U;
|
||||
|
||||
|
@ -51,10 +52,10 @@ unsigned char* CDMRSlot::m_idle = NULL;
|
|||
|
||||
FLCO CDMRSlot::m_flco1;
|
||||
unsigned char CDMRSlot::m_id1 = 0U;
|
||||
bool CDMRSlot::m_voice1 = true;
|
||||
ACTIVITY_TYPE CDMRSlot::m_activity1 = ACTIVITY_NONE;
|
||||
FLCO CDMRSlot::m_flco2;
|
||||
unsigned char CDMRSlot::m_id2 = 0U;
|
||||
bool CDMRSlot::m_voice2 = true;
|
||||
ACTIVITY_TYPE CDMRSlot::m_activity2 = ACTIVITY_NONE;
|
||||
|
||||
const unsigned char TALKER_ID_NONE = 0x00U;
|
||||
const unsigned char TALKER_ID_HEADER = 0x01U;
|
||||
|
@ -77,6 +78,7 @@ m_rfEmbeddedData(NULL),
|
|||
m_rfEmbeddedReadN(0U),
|
||||
m_rfEmbeddedWriteN(1U),
|
||||
m_rfTalkerId(TALKER_ID_NONE),
|
||||
m_rfTalkerAlias(NULL),
|
||||
m_netEmbeddedLC(),
|
||||
m_netEmbeddedData(NULL),
|
||||
m_netEmbeddedReadN(0U),
|
||||
|
@ -113,6 +115,7 @@ m_aveRSSI(0U),
|
|||
m_rssiCount(0U),
|
||||
m_fp(NULL)
|
||||
{
|
||||
m_rfTalkerAlias = new unsigned char[32U];
|
||||
m_lastFrame = new unsigned char[DMR_FRAME_LENGTH_BYTES + 2U];
|
||||
|
||||
m_rfEmbeddedData = new CDMREmbeddedData[2U];
|
||||
|
@ -126,6 +129,7 @@ CDMRSlot::~CDMRSlot()
|
|||
delete[] m_rfEmbeddedData;
|
||||
delete[] m_netEmbeddedData;
|
||||
delete[] m_lastFrame;
|
||||
delete[] m_rfTalkerAlias;
|
||||
}
|
||||
|
||||
bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||
|
@ -267,7 +271,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
std::string dst = m_lookup->find(dstId);
|
||||
|
||||
if (m_netState == RS_NET_IDLE) {
|
||||
setShortLC(m_slotNo, dstId, flco, true);
|
||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
||||
m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "R");
|
||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||
}
|
||||
|
@ -332,6 +336,8 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
else
|
||||
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
|
||||
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
||||
|
||||
if (m_rfTimeout) {
|
||||
writeEndRF();
|
||||
return false;
|
||||
|
@ -391,7 +397,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
std::string dst = m_lookup->find(dstId);
|
||||
|
||||
if (m_netState == RS_NET_IDLE) {
|
||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, false);
|
||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
||||
m_display->writeDMR(m_slotNo, src, gi, dst, "R");
|
||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||
}
|
||||
|
@ -470,6 +476,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
break;
|
||||
}
|
||||
|
||||
// If data preamble, signal its existence
|
||||
if (m_netState == RS_NET_IDLE && csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
|
||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
||||
m_display->writeDMR(m_slotNo, src, gi, dst, "R");
|
||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||
}
|
||||
|
||||
return true;
|
||||
} 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)
|
||||
|
@ -599,6 +612,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
logGPSPosition(data);
|
||||
}
|
||||
if (m_network != NULL)
|
||||
m_network->writePosition(m_rfLC->getSrcId(), data);
|
||||
|
@ -609,6 +623,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 0U, data);
|
||||
|
||||
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias, data, 6U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "R");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -623,6 +642,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 1U, data);
|
||||
|
||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias + 6U, data, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "R");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -637,6 +661,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 2U, data);
|
||||
|
||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
::memset(m_rfTalkerAlias, 0, 32U);
|
||||
::memcpy(m_rfTalkerAlias + 6U + 7U, data, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "R");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -651,6 +680,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 3U, data);
|
||||
|
||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias + 6U + 7U + 7U, data, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "R");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -810,7 +844,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
std::string dst = m_lookup->find(dstId);
|
||||
|
||||
if (m_netState == RS_NET_IDLE) {
|
||||
setShortLC(m_slotNo, dstId, flco, true);
|
||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
||||
m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "R");
|
||||
m_display->writeDMRRSSI(m_slotNo, m_rssi);
|
||||
m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F);
|
||||
|
@ -1025,7 +1059,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
m_netState = RS_NET_AUDIO;
|
||||
|
||||
setShortLC(m_slotNo, dstId, flco, true);
|
||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
||||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
std::string dst = m_lookup->find(dstId);
|
||||
|
@ -1093,7 +1127,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
m_netState = RS_NET_AUDIO;
|
||||
|
||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), true);
|
||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
||||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
std::string dst = m_lookup->find(dstId);
|
||||
|
@ -1163,7 +1197,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
// We've received the voice header and terminator haven't we?
|
||||
m_netFrames += 2U;
|
||||
LogMessage("DMR Slot %u, received network end of voice transmission, %.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));
|
||||
|
||||
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
||||
writeEndNet();
|
||||
} else if (dataType == DT_DATA_HEADER) {
|
||||
if (m_netState == RS_NET_DATA)
|
||||
|
@ -1205,7 +1239,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
m_netState = RS_NET_DATA;
|
||||
|
||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, false);
|
||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
||||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
std::string dst = m_lookup->find(dstId);
|
||||
|
@ -1283,7 +1317,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
m_netState = RS_NET_AUDIO;
|
||||
|
||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), true);
|
||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
||||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
std::string dst = m_lookup->find(dstId);
|
||||
|
@ -1370,10 +1404,16 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
logGPSPosition(data);
|
||||
}
|
||||
break;
|
||||
case FLCO_TALKER_ALIAS_HEADER:
|
||||
if (!(m_netTalkerId & TALKER_ID_HEADER)) {
|
||||
if (!m_netTalkerId)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias, data + 2U, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "N");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -1384,6 +1424,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
break;
|
||||
case FLCO_TALKER_ALIAS_BLOCK1:
|
||||
if (!(m_netTalkerId & TALKER_ID_BLOCK1)) {
|
||||
if (!m_netTalkerId)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias + 7U, data + 2U, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "N");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -1394,6 +1439,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
break;
|
||||
case FLCO_TALKER_ALIAS_BLOCK2:
|
||||
if (!(m_netTalkerId & TALKER_ID_BLOCK2)) {
|
||||
if (!m_netTalkerId)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias + 7U + 7U, data + 2U, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "N");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -1404,6 +1454,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
break;
|
||||
case FLCO_TALKER_ALIAS_BLOCK3:
|
||||
if (!(m_netTalkerId & TALKER_ID_BLOCK3)) {
|
||||
if (!m_netTalkerId)
|
||||
::memset(m_rfTalkerAlias, '\0', 32U);
|
||||
::memcpy(m_rfTalkerAlias + 7U + 7U + 7U, data+2U, 7U);
|
||||
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias, "N");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
|
||||
CUtils::dump(2U, text, data, 9U);
|
||||
|
@ -1523,6 +1578,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
LogWarning("DMR Slot %u, unhandled network CSBK type - 0x%02X", m_slotNo, csbko);
|
||||
break;
|
||||
}
|
||||
|
||||
// If data preamble, signal its existence
|
||||
if (csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
|
||||
setShortLC(m_slotNo, dstId, gi ? FLCO_GROUP : FLCO_USER_USER, ACTIVITY_DATA);
|
||||
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) {
|
||||
if (m_netState != RS_NET_DATA || m_netFrames == 0U)
|
||||
return;
|
||||
|
@ -1574,6 +1635,54 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CDMRSlot::logGPSPosition(const unsigned char* data)
|
||||
{
|
||||
unsigned int errorI = (data[2U] & 0x0E) >> 1U;
|
||||
|
||||
const char* error;
|
||||
switch (errorI) {
|
||||
case 0U:
|
||||
error = "< 2m";
|
||||
break;
|
||||
case 1U:
|
||||
error = "< 20m";
|
||||
break;
|
||||
case 2U:
|
||||
error = "< 200m";
|
||||
break;
|
||||
case 3U:
|
||||
error = "< 2km";
|
||||
break;
|
||||
case 4U:
|
||||
error = "< 20km";
|
||||
break;
|
||||
case 5U:
|
||||
error = "< 200km";
|
||||
break;
|
||||
case 6U:
|
||||
error = "> 200km";
|
||||
break;
|
||||
default:
|
||||
error = "not known";
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t longitudeI = ((data[2U] & 0x01U) << 31) | (data[3U] << 23) | (data[4U] << 15) | (data[5U] << 7);
|
||||
longitudeI >>= 7;
|
||||
|
||||
int32_t latitudeI = (data[6U] << 24) | (data[7U] << 16) | (data[8U] << 8);
|
||||
latitudeI >>= 8;
|
||||
|
||||
float longitude = 360.0F / 33554432.0F; // 360/2^25 steps
|
||||
float latitude = 180.0F / 16777216.0F; // 180/2^24 steps
|
||||
|
||||
longitude *= float(longitudeI);
|
||||
latitude *= float(latitudeI);
|
||||
|
||||
LogMessage("GPS position [%f,%f] (Position error %s)", latitude, longitude, error);
|
||||
}
|
||||
|
||||
void CDMRSlot::clock()
|
||||
{
|
||||
unsigned int ms = m_interval.elapsed();
|
||||
|
@ -1737,7 +1846,7 @@ void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData
|
|||
}
|
||||
|
||||
|
||||
void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool voice)
|
||||
void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, ACTIVITY_TYPE type)
|
||||
{
|
||||
assert(m_modem != NULL);
|
||||
|
||||
|
@ -1745,7 +1854,7 @@ void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool
|
|||
case 1U:
|
||||
m_id1 = 0U;
|
||||
m_flco1 = flco;
|
||||
m_voice1 = voice;
|
||||
m_activity1 = type;
|
||||
if (id != 0U) {
|
||||
unsigned char buffer[3U];
|
||||
buffer[0U] = (id << 16) & 0xFFU;
|
||||
|
@ -1757,7 +1866,7 @@ void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool
|
|||
case 2U:
|
||||
m_id2 = 0U;
|
||||
m_flco2 = flco;
|
||||
m_voice2 = voice;
|
||||
m_activity2 = type;
|
||||
if (id != 0U) {
|
||||
unsigned char buffer[3U];
|
||||
buffer[0U] = (id << 16) & 0xFFU;
|
||||
|
@ -1783,32 +1892,42 @@ void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool
|
|||
|
||||
if (m_id1 != 0U) {
|
||||
lc[2U] = m_id1;
|
||||
if (m_voice1) {
|
||||
if (m_flco1 == FLCO_GROUP)
|
||||
lc[1U] |= 0x80U;
|
||||
else
|
||||
lc[1U] |= 0x90U;
|
||||
} else {
|
||||
if (m_flco1 == FLCO_GROUP)
|
||||
lc[1U] |= 0xB0U;
|
||||
else
|
||||
lc[1U] |= 0xA0U;
|
||||
}
|
||||
if (m_activity1 == ACTIVITY_VOICE && m_flco1 == FLCO_GROUP)
|
||||
lc[1U] |= 0x08U;
|
||||
else if (m_activity1 == ACTIVITY_VOICE && m_flco1 == FLCO_USER_USER)
|
||||
lc[1U] |= 0x09U;
|
||||
else if (m_activity1 == ACTIVITY_DATA && m_flco1 == FLCO_GROUP)
|
||||
lc[1U] |= 0x0BU;
|
||||
else if (m_activity1 == ACTIVITY_DATA && m_flco1 == FLCO_USER_USER)
|
||||
lc[1U] |= 0x0AU;
|
||||
else if (m_activity1 == ACTIVITY_CSBK && m_flco1 == FLCO_GROUP)
|
||||
lc[1U] |= 0x02U;
|
||||
else if (m_activity1 == ACTIVITY_CSBK && m_flco1 == FLCO_USER_USER)
|
||||
lc[1U] |= 0x03U;
|
||||
else if (m_activity1 == ACTIVITY_EMERG && m_flco1 == FLCO_GROUP)
|
||||
lc[1U] |= 0x0CU;
|
||||
else if (m_activity1 == ACTIVITY_EMERG && m_flco1 == FLCO_USER_USER)
|
||||
lc[1U] |= 0x0DU;
|
||||
}
|
||||
|
||||
if (m_id2 != 0U) {
|
||||
lc[3U] = m_id2;
|
||||
if (m_voice2) {
|
||||
if (m_flco2 == FLCO_GROUP)
|
||||
lc[1U] |= 0x08U;
|
||||
else
|
||||
lc[1U] |= 0x09U;
|
||||
} else {
|
||||
if (m_flco2 == FLCO_GROUP)
|
||||
lc[1U] |= 0x0BU;
|
||||
else
|
||||
lc[1U] |= 0x0AU;
|
||||
}
|
||||
if (m_activity2 == ACTIVITY_VOICE && m_flco2 == FLCO_GROUP)
|
||||
lc[1U] |= 0x80U;
|
||||
else if (m_activity2 == ACTIVITY_VOICE && m_flco2 == FLCO_USER_USER)
|
||||
lc[1U] |= 0x90U;
|
||||
else if (m_activity2 == ACTIVITY_DATA && m_flco2 == FLCO_GROUP)
|
||||
lc[1U] |= 0xB0U;
|
||||
else if (m_activity2 == ACTIVITY_DATA && m_flco2 == FLCO_USER_USER)
|
||||
lc[1U] |= 0xA0U;
|
||||
else if (m_activity2 == ACTIVITY_CSBK && m_flco2 == FLCO_GROUP)
|
||||
lc[1U] |= 0x20U;
|
||||
else if (m_activity2 == ACTIVITY_CSBK && m_flco2 == FLCO_USER_USER)
|
||||
lc[1U] |= 0x30U;
|
||||
else if (m_activity2 == ACTIVITY_EMERG && m_flco2 == FLCO_GROUP)
|
||||
lc[1U] |= 0xC0U;
|
||||
else if (m_activity2 == ACTIVITY_EMERG && m_flco2 == FLCO_USER_USER)
|
||||
lc[1U] |= 0xD0U;
|
||||
}
|
||||
|
||||
lc[4U] = CCRC::crc8(lc, 4U);
|
||||
|
|
17
DMRSlot.h
17
DMRSlot.h
|
@ -36,6 +36,14 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
enum ACTIVITY_TYPE {
|
||||
ACTIVITY_NONE,
|
||||
ACTIVITY_VOICE,
|
||||
ACTIVITY_DATA,
|
||||
ACTIVITY_CSBK,
|
||||
ACTIVITY_EMERG
|
||||
};
|
||||
|
||||
class CDMRSlot {
|
||||
public:
|
||||
CDMRSlot(unsigned int slotNo, unsigned int timeout);
|
||||
|
@ -61,6 +69,7 @@ private:
|
|||
unsigned int m_rfEmbeddedReadN;
|
||||
unsigned int m_rfEmbeddedWriteN;
|
||||
unsigned char m_rfTalkerId;
|
||||
unsigned char* m_rfTalkerAlias;
|
||||
CDMREmbeddedData m_netEmbeddedLC;
|
||||
CDMREmbeddedData* m_netEmbeddedData;
|
||||
unsigned int m_netEmbeddedReadN;
|
||||
|
@ -118,10 +127,12 @@ private:
|
|||
|
||||
static FLCO m_flco1;
|
||||
static unsigned char m_id1;
|
||||
static bool m_voice1;
|
||||
static ACTIVITY_TYPE m_activity1;
|
||||
static FLCO m_flco2;
|
||||
static unsigned char m_id2;
|
||||
static bool m_voice2;
|
||||
static ACTIVITY_TYPE m_activity2;
|
||||
|
||||
void logGPSPosition(const unsigned char* data);
|
||||
|
||||
void writeQueueRF(const unsigned char* data);
|
||||
void writeQueueNet(const unsigned char* data);
|
||||
|
@ -138,7 +149,7 @@ private:
|
|||
bool insertSilence(const unsigned char* data, unsigned char seqNo);
|
||||
void insertSilence(unsigned int count);
|
||||
|
||||
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true);
|
||||
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, ACTIVITY_TYPE type = ACTIVITY_NONE);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,11 +36,13 @@ bool CallsignCompare(const std::string& arg, const unsigned char* my)
|
|||
|
||||
// #define DUMP_DSTAR
|
||||
|
||||
CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool errorReply, const std::vector<std::string>& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper) :
|
||||
CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool errorReply, const std::vector<std::string>& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper) :
|
||||
m_callsign(NULL),
|
||||
m_gateway(NULL),
|
||||
m_selfOnly(selfOnly),
|
||||
m_ackReply(ackReply),
|
||||
m_errorReply(errorReply),
|
||||
m_remoteGateway(remoteGateway),
|
||||
m_blackList(blackList),
|
||||
m_network(network),
|
||||
m_display(display),
|
||||
|
@ -58,8 +60,8 @@ m_networkWatchdog(1000U, 0U, 1500U),
|
|||
m_rfTimeoutTimer(1000U, timeout),
|
||||
m_netTimeoutTimer(1000U, timeout),
|
||||
m_packetTimer(1000U, 0U, 300U),
|
||||
m_ackTimer(1000U, 0U, 750U),
|
||||
m_errTimer(1000U, 0U, 750U),
|
||||
m_ackTimer(1000U, 0U, ackTime),
|
||||
m_errTimer(1000U, 0U, ackTime),
|
||||
m_interval(),
|
||||
m_elapsed(),
|
||||
m_rfFrames(0U),
|
||||
|
@ -523,6 +525,7 @@ void CDStarControl::writeEndRF()
|
|||
|
||||
if (m_netState == RS_NET_IDLE) {
|
||||
m_display->clearDStar();
|
||||
|
||||
m_ackTimer.start();
|
||||
|
||||
if (m_network != NULL)
|
||||
|
@ -587,7 +590,6 @@ void CDStarControl::writeNetwork()
|
|||
|
||||
m_netTimeoutTimer.start();
|
||||
m_packetTimer.start();
|
||||
//m_elapsed.start(); // commented out and placed lower down due to delay introduced somewhere below here.
|
||||
m_ackTimer.stop();
|
||||
m_errTimer.stop();
|
||||
|
||||
|
@ -601,6 +603,13 @@ void CDStarControl::writeNetwork()
|
|||
m_netBits = 1U;
|
||||
m_netErrs = 0U;
|
||||
|
||||
if (m_remoteGateway) {
|
||||
header.setRepeater(true);
|
||||
header.setRPTCall1(m_callsign);
|
||||
header.setRPTCall2(m_callsign);
|
||||
header.get(data + 1U);
|
||||
}
|
||||
|
||||
writeQueueHeaderNet(data);
|
||||
|
||||
#if defined(DUMP_DSTAR)
|
||||
|
@ -1011,6 +1020,9 @@ void CDStarControl::sendAck()
|
|||
{
|
||||
m_rfTimeoutTimer.stop();
|
||||
|
||||
if (!m_ackReply)
|
||||
return;
|
||||
|
||||
unsigned char user[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
m_rfHeader.getMyCall1(user);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
class CDStarControl {
|
||||
public:
|
||||
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool errorReply, const std::vector<std::string>& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper);
|
||||
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool errorReply, const std::vector<std::string>& blackList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
||||
~CDStarControl();
|
||||
|
||||
bool writeModem(unsigned char* data, unsigned int len);
|
||||
|
@ -50,7 +50,9 @@ private:
|
|||
unsigned char* m_callsign;
|
||||
unsigned char* m_gateway;
|
||||
bool m_selfOnly;
|
||||
bool m_ackReply;
|
||||
bool m_errorReply;
|
||||
bool m_remoteGateway;
|
||||
std::vector<std::string> m_blackList;
|
||||
CDStarNetwork* m_network;
|
||||
CDisplay* m_display;
|
||||
|
|
|
@ -36,6 +36,7 @@ const unsigned char TAG_EOT = 0x03U;
|
|||
enum HW_TYPE {
|
||||
HWT_MMDVM,
|
||||
HWT_DVMEGA,
|
||||
HWT_MMDVM_HS,
|
||||
HWT_UNKNOWN
|
||||
};
|
||||
|
||||
|
|
56
Display.cpp
56
Display.cpp
|
@ -18,14 +18,15 @@
|
|||
|
||||
#include "Display.h"
|
||||
#include "Defines.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
CDisplay::CDisplay() :
|
||||
m_timer1(1000U, 3U),
|
||||
m_timer2(1000U, 3U),
|
||||
m_timer1(3000U, 3U),
|
||||
m_timer2(3000U, 3U),
|
||||
m_mode1(MODE_IDLE),
|
||||
m_mode2(MODE_IDLE)
|
||||
{
|
||||
|
@ -117,7 +118,6 @@ void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group,
|
|||
m_timer2.start();
|
||||
m_mode2 = MODE_IDLE;
|
||||
}
|
||||
|
||||
writeDMRInt(slotNo, src, group, dst, type);
|
||||
}
|
||||
|
||||
|
@ -127,11 +127,55 @@ void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi)
|
|||
writeDMRRSSIInt(slotNo, rssi);
|
||||
}
|
||||
|
||||
void CDisplay::writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
|
||||
{
|
||||
char TA[32U];
|
||||
unsigned char *b;
|
||||
unsigned char c;
|
||||
int j;
|
||||
unsigned int i,t1,t2, TAsize, TAformat;
|
||||
|
||||
if (strcmp(type," ")==0) { writeDMRTAInt(slotNo, (unsigned char*)TA, type); return; }
|
||||
|
||||
TAformat=(talkerAlias[0]>>6U) & 0x03U;
|
||||
TAsize = (talkerAlias[0]>>1U) & 0x1FU;
|
||||
::strcpy(TA,"(could not decode)");
|
||||
switch (TAformat) {
|
||||
case 0U: // 7 bit
|
||||
::memset (&TA,0,32U);
|
||||
b=&talkerAlias[0];
|
||||
t1=0; t2=0; c=0;
|
||||
for (i=0;(i<32U)&&(t2<TAsize);i++) {
|
||||
for (j=7U;j>=0;j--) {
|
||||
c = (c<<1U) | (b[i] >> j);
|
||||
if (++t1==7U) { if (i>0) {TA[t2++]=c & 0x7FU; } t1=0; c=0; }
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1U: // ISO 8 bit
|
||||
case 2U: // UTF8
|
||||
::strcpy(TA,(char*)talkerAlias+1U);
|
||||
break;
|
||||
case 3U: // UTF16 poor man's conversion
|
||||
t2=0;
|
||||
::memset (&TA,0,32U);
|
||||
for(i=0;(i<15)&&(t2<TAsize);i++) {
|
||||
if (talkerAlias[2U*i+1U]==0)
|
||||
TA[t2++]=talkerAlias[2U*i+2U]; else TA[t2++]='?';
|
||||
}
|
||||
TA[TAsize]=0;
|
||||
break;
|
||||
}
|
||||
LogMessage("DMR Talker Alias (Data Format %u, Received %u/%u char): '%s'", TAformat, ::strlen(TA), TAsize, TA);
|
||||
if (::strlen(TA)>TAsize) { if (strlen(TA)<29U) strcat(TA," ?"); else strcpy(TA+28U," ?"); }
|
||||
if (strlen((char*)TA)>=4U) writeDMRTAInt(slotNo, (unsigned char*)TA, type);
|
||||
|
||||
}
|
||||
|
||||
void CDisplay::writeDMRBER(unsigned int slotNo, float ber)
|
||||
{
|
||||
writeDMRBERInt(slotNo, ber);
|
||||
}
|
||||
|
||||
void CDisplay::clearDMR(unsigned int slotNo)
|
||||
{
|
||||
if (slotNo == 1U) {
|
||||
|
@ -293,6 +337,10 @@ void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
|||
{
|
||||
}
|
||||
|
||||
void CDisplay::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
|
||||
{
|
||||
}
|
||||
|
||||
void CDisplay::writeDMRBERInt(unsigned int slotNo, float ber)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||
void writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
|
||||
void writeDMRBER(unsigned int slotNo, float ber);
|
||||
void writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||
void clearDMR(unsigned int slotNo);
|
||||
|
||||
void writeFusion(const char* source, const char* dest, const char* type, const char* origin);
|
||||
|
@ -74,6 +75,7 @@ protected:
|
|||
|
||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0;
|
||||
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
||||
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
||||
virtual void clearDMRInt(unsigned int slotNo) = 0;
|
||||
|
||||
|
|
187
JitterBuffer.cpp
Normal file
187
JitterBuffer.cpp
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "JitterBuffer.h"
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
CJitterBuffer::CJitterBuffer(unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug) :
|
||||
m_blockSize(blockSize),
|
||||
m_blockTime(blockTime),
|
||||
m_topSequenceNumber(topSequenceNumber),
|
||||
m_debug(debug),
|
||||
m_blockCount(0U),
|
||||
m_timer(1000U, 0U, jitterTime),
|
||||
m_stopWatch(),
|
||||
m_running(false),
|
||||
m_buffer(NULL),
|
||||
m_headSequenceNumber(0U),
|
||||
m_lastData(NULL),
|
||||
m_lastDataLength(0U)
|
||||
{
|
||||
assert(blockSize > 0U);
|
||||
assert(blockTime > 0U);
|
||||
assert(jitterTime > 0U);
|
||||
assert(topSequenceNumber > 0U);
|
||||
|
||||
m_blockCount = (jitterTime / blockTime) * 2U + 1U;
|
||||
|
||||
m_buffer = new JitterEntry[m_blockCount];
|
||||
|
||||
for (unsigned int i = 0U; i < m_blockCount; i++)
|
||||
m_buffer[i].m_data = new unsigned char[m_blockSize];
|
||||
|
||||
m_lastData = new unsigned char[m_blockSize];
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
CJitterBuffer::~CJitterBuffer()
|
||||
{
|
||||
for (unsigned int i = 0U; i < m_blockCount; i++)
|
||||
delete[] m_buffer[i].m_data;
|
||||
|
||||
delete[] m_buffer;
|
||||
delete[] m_lastData;
|
||||
}
|
||||
|
||||
bool CJitterBuffer::addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
assert(length <= m_blockSize);
|
||||
|
||||
unsigned int headSequenceNumber = m_headSequenceNumber % m_topSequenceNumber;
|
||||
unsigned int tailSequenceNumber = (m_headSequenceNumber + m_blockCount) % m_topSequenceNumber;
|
||||
|
||||
// Is the data out of sequence?
|
||||
if (headSequenceNumber < tailSequenceNumber) {
|
||||
if (sequenceNumber < headSequenceNumber || sequenceNumber >= tailSequenceNumber) {
|
||||
if (m_debug)
|
||||
LogDebug("JitterBuffer: rejecting frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (sequenceNumber >= tailSequenceNumber && sequenceNumber < headSequenceNumber) {
|
||||
if (m_debug)
|
||||
LogDebug("JitterBuffer: rejecting frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int number;
|
||||
if (sequenceNumber >= headSequenceNumber)
|
||||
number = sequenceNumber - headSequenceNumber;
|
||||
else
|
||||
number = (sequenceNumber + m_blockCount) - headSequenceNumber;;
|
||||
|
||||
unsigned int index = (m_headSequenceNumber + number) % m_blockCount;
|
||||
|
||||
// Do we already have the data?
|
||||
if (m_buffer[index].m_length > 0U) {
|
||||
if (m_debug)
|
||||
LogDebug("JitterBuffer: rejecting duplicate frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogDebug("JitterBuffer: adding frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
|
||||
::memcpy(m_buffer[index].m_data, data, length);
|
||||
m_buffer[index].m_length = length;
|
||||
|
||||
if (!m_timer.isRunning()) {
|
||||
LogDebug("JitterBuffer: starting the timer");
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JB_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (!m_running)
|
||||
return JBS_NO_DATA;
|
||||
|
||||
unsigned int sequenceNumber = m_stopWatch.elapsed() / m_blockTime + 3U;
|
||||
if (m_headSequenceNumber > sequenceNumber)
|
||||
return JBS_NO_DATA;
|
||||
|
||||
unsigned int head = m_headSequenceNumber % m_blockCount;
|
||||
|
||||
m_headSequenceNumber++;
|
||||
|
||||
if (m_buffer[head].m_length > 0U) {
|
||||
LogDebug("JitterBuffer: returning data, elapsed=%ums, raw=%u, head=%u", m_stopWatch.elapsed(), m_headSequenceNumber - 1U, head);
|
||||
|
||||
::memcpy(data, m_buffer[head].m_data, m_buffer[head].m_length);
|
||||
length = m_buffer[head].m_length;
|
||||
|
||||
// Save this data in case no more data is available next time
|
||||
::memcpy(m_lastData, m_buffer[head].m_data, m_buffer[head].m_length);
|
||||
m_lastDataLength = m_buffer[head].m_length;
|
||||
|
||||
m_buffer[head].m_length = 0U;
|
||||
|
||||
return JBS_DATA;
|
||||
}
|
||||
|
||||
if (m_debug)
|
||||
LogDebug("JitterBuffer: no data available, elapsed=%ums, raw=%u, head=%u", m_stopWatch.elapsed(), m_headSequenceNumber - 1U, head);
|
||||
|
||||
// Return the last data frame if we have it
|
||||
if (m_lastDataLength > 0U) {
|
||||
LogDebug("JitterBuffer: returning the last received frame");
|
||||
::memcpy(data, m_lastData, m_lastDataLength);
|
||||
length = m_lastDataLength;
|
||||
|
||||
return JBS_MISSING;
|
||||
}
|
||||
|
||||
return JBS_NO_DATA;
|
||||
}
|
||||
|
||||
void CJitterBuffer::reset()
|
||||
{
|
||||
for (unsigned int i = 0U; i < m_blockCount; i++)
|
||||
m_buffer[i].m_length = 0U;
|
||||
|
||||
m_headSequenceNumber = 0U;
|
||||
|
||||
m_lastDataLength = 0U;
|
||||
|
||||
m_timer.stop();
|
||||
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
void CJitterBuffer::clock(unsigned int ms)
|
||||
{
|
||||
m_timer.clock(ms);
|
||||
if (m_timer.isRunning() && m_timer.hasExpired()) {
|
||||
if (!m_running) {
|
||||
m_stopWatch.start();
|
||||
m_running = true;
|
||||
}
|
||||
}
|
||||
}
|
67
JitterBuffer.h
Normal file
67
JitterBuffer.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(JITTERBUFFER_H)
|
||||
#define JITTERBUFFER_H
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "Timer.h"
|
||||
|
||||
enum JB_STATUS {
|
||||
JBS_NO_DATA,
|
||||
JBS_DATA,
|
||||
JBS_MISSING
|
||||
};
|
||||
|
||||
class CJitterBuffer {
|
||||
public:
|
||||
CJitterBuffer(unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug);
|
||||
~CJitterBuffer();
|
||||
|
||||
bool addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber);
|
||||
|
||||
JB_STATUS getData(unsigned char* data, unsigned int& length);
|
||||
|
||||
void reset();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
private:
|
||||
unsigned int m_blockSize;
|
||||
unsigned int m_blockTime;
|
||||
unsigned int m_topSequenceNumber;
|
||||
bool m_debug;
|
||||
unsigned int m_blockCount;
|
||||
CTimer m_timer;
|
||||
CStopWatch m_stopWatch;
|
||||
bool m_running;
|
||||
|
||||
struct JitterEntry
|
||||
{
|
||||
unsigned char* m_data;
|
||||
unsigned int m_length;
|
||||
};
|
||||
|
||||
JitterEntry* m_buffer;
|
||||
unsigned int m_headSequenceNumber;
|
||||
|
||||
unsigned char* m_lastData;
|
||||
unsigned int m_lastDataLength;
|
||||
};
|
||||
|
||||
#endif
|
30
MMDVM.ini
30
MMDVM.ini
|
@ -1,5 +1,6 @@
|
|||
[General]
|
||||
Callsign=G9BF
|
||||
Id=123456
|
||||
Timeout=180
|
||||
Duplex=1
|
||||
# ModeHang=10
|
||||
|
@ -42,9 +43,13 @@ TXInvert=1
|
|||
RXInvert=0
|
||||
PTTInvert=0
|
||||
TXDelay=100
|
||||
RXOffset=0
|
||||
TXOffset=0
|
||||
DMRDelay=0
|
||||
RXLevel=50
|
||||
TXLevel=50
|
||||
RXDCOffset=0
|
||||
TXDCOffset=0
|
||||
# CWIdTXLevel=50
|
||||
# D-StarTXLevel=50
|
||||
# DMRTXLevel=50
|
||||
|
@ -63,12 +68,15 @@ Port=/dev/ttyACM1
|
|||
Enable=1
|
||||
Module=C
|
||||
SelfOnly=0
|
||||
AckReply=1
|
||||
AckTime=750
|
||||
ErrorReply=1
|
||||
RemoteGateway=0
|
||||
# ModeHang=10
|
||||
|
||||
[DMR]
|
||||
Enable=1
|
||||
Beacons=1
|
||||
Id=123456
|
||||
ColorCode=1
|
||||
SelfOnly=0
|
||||
EmbeddedLCOnly=0
|
||||
|
@ -78,22 +86,30 @@ DumpTAData=1
|
|||
# Slot2TGWhiteList=
|
||||
CallHang=3
|
||||
TXHang=4
|
||||
# ModeHang=10
|
||||
|
||||
[System Fusion]
|
||||
Enable=1
|
||||
LowDeviation=0
|
||||
SelfOnly=0
|
||||
#DSQ=1
|
||||
RemoteGateway=0
|
||||
# ModeHang=10
|
||||
|
||||
[P25]
|
||||
Enable=1
|
||||
NAC=293
|
||||
SelfOnly=0
|
||||
OverrideUIDCheck=0
|
||||
RemoteGateway=0
|
||||
# ModeHang=10
|
||||
|
||||
[D-Star Network]
|
||||
Enable=1
|
||||
GatewayAddress=127.0.0.1
|
||||
GatewayPort=20010
|
||||
LocalPort=20011
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[DMR Network]
|
||||
|
@ -101,19 +117,21 @@ Enable=1
|
|||
Address=44.131.4.1
|
||||
Port=62031
|
||||
Jitter=300
|
||||
# Local=3350
|
||||
# Local=62032
|
||||
Password=PASSWORD
|
||||
# Options=
|
||||
Slot1=1
|
||||
Slot2=1
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[System Fusion Network]
|
||||
Enable=1
|
||||
LocalAddress=127.0.0.1
|
||||
LocalPort=3200
|
||||
GwyAddress=127.0.0.1
|
||||
GwyPort=4200
|
||||
GatewayAddress=127.0.0.1
|
||||
GatewayPort=4200
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[P25 Network]
|
||||
|
@ -121,6 +139,7 @@ Enable=1
|
|||
GatewayAddress=127.0.0.1
|
||||
GatewayPort=42020
|
||||
LocalPort=32010
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[TFT Serial]
|
||||
|
@ -154,12 +173,15 @@ Port=/dev/ttyAMA0
|
|||
Brightness=50
|
||||
DisplayClock=1
|
||||
UTC=0
|
||||
#Screen Layout: 0=G4KLX 2=ON7LDS
|
||||
ScreenLayout=2
|
||||
IdleBrightness=20
|
||||
|
||||
[OLED]
|
||||
Type=3
|
||||
Brightness=0
|
||||
Invert=0
|
||||
Scroll=1
|
||||
|
||||
[LCDproc]
|
||||
Address=localhost
|
||||
|
|
194
MMDVMHost.cpp
194
MMDVMHost.cpp
|
@ -95,6 +95,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
::signal(SIGINT, sigHandler);
|
||||
::signal(SIGTERM, sigHandler);
|
||||
::signal(SIGHUP, sigHandler);
|
||||
#endif
|
||||
|
@ -109,11 +110,14 @@ int main(int argc, char** argv)
|
|||
|
||||
delete host;
|
||||
|
||||
if (m_signal == 2)
|
||||
::LogInfo("MMDVMHost-%s exited on receipt of SIGINT", VERSION);
|
||||
|
||||
if (m_signal == 15)
|
||||
::LogInfo("Caught SIGTERM, exiting");
|
||||
::LogInfo("MMDVMHost-%s exited on receipt of SIGTERM", VERSION);
|
||||
|
||||
if (m_signal == 1)
|
||||
::LogInfo("Caught SIGHUP, restarting");
|
||||
::LogInfo("MMDVMHost-%s is restarting on receipt of SIGHUP", VERSION);
|
||||
} while (m_signal == 1);
|
||||
|
||||
::LogFinalise();
|
||||
|
@ -131,8 +135,14 @@ m_p25Network(NULL),
|
|||
m_display(NULL),
|
||||
m_ump(NULL),
|
||||
m_mode(MODE_IDLE),
|
||||
m_rfModeHang(10U),
|
||||
m_netModeHang(3U),
|
||||
m_dstarRFModeHang(10U),
|
||||
m_dmrRFModeHang(10U),
|
||||
m_ysfRFModeHang(10U),
|
||||
m_p25RFModeHang(10U),
|
||||
m_dstarNetModeHang(3U),
|
||||
m_dmrNetModeHang(3U),
|
||||
m_ysfNetModeHang(3U),
|
||||
m_p25NetModeHang(3U),
|
||||
m_modeTimer(1000U),
|
||||
m_dmrTXTimer(1000U),
|
||||
m_cwIdTimer(1000U),
|
||||
|
@ -145,6 +155,7 @@ m_p25Enabled(false),
|
|||
m_cwIdTime(0U),
|
||||
m_lookup(NULL),
|
||||
m_callsign(),
|
||||
m_id(0U),
|
||||
m_cwCallsign()
|
||||
{
|
||||
}
|
||||
|
@ -334,17 +345,25 @@ int CMMDVMHost::run()
|
|||
std::string module = m_conf.getDStarModule();
|
||||
bool selfOnly = m_conf.getDStarSelfOnly();
|
||||
std::vector<std::string> blackList = m_conf.getDStarBlackList();
|
||||
bool ackReply = m_conf.getDStarAckReply();
|
||||
unsigned int ackTime = m_conf.getDStarAckTime();
|
||||
bool errorReply = m_conf.getDStarErrorReply();
|
||||
bool remoteGateway = m_conf.getDStarRemoteGateway();
|
||||
m_dstarRFModeHang = m_conf.getDStarModeHang();
|
||||
|
||||
LogInfo("D-Star Parameters");
|
||||
LogInfo("D-Star RF Parameters");
|
||||
LogInfo(" Module: %s", module.c_str());
|
||||
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
||||
LogInfo(" Ack Reply: %s", ackReply ? "yes" : "no");
|
||||
LogInfo(" Ack Time: %ums", ackTime);
|
||||
LogInfo(" Error Reply: %s", errorReply ? "yes" : "no");
|
||||
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");
|
||||
LogInfo(" Mode Hang: %us", m_dstarRFModeHang);
|
||||
|
||||
if (blackList.size() > 0U)
|
||||
LogInfo(" Black List: %u", blackList.size());
|
||||
|
||||
dstar = new CDStarControl(m_callsign, module, selfOnly, errorReply, blackList, m_dstarNetwork, m_display, m_timeout, m_duplex, rssi);
|
||||
dstar = new CDStarControl(m_callsign, module, selfOnly, ackReply, ackTime, errorReply, blackList, m_dstarNetwork, m_display, m_timeout, m_duplex, remoteGateway, rssi);
|
||||
}
|
||||
|
||||
CDMRControl* dmr = NULL;
|
||||
|
@ -362,16 +381,20 @@ int CMMDVMHost::run()
|
|||
unsigned int callHang = m_conf.getDMRCallHang();
|
||||
unsigned int txHang = m_conf.getDMRTXHang();
|
||||
unsigned int jitter = m_conf.getDMRNetworkJitter();
|
||||
m_dmrRFModeHang = m_conf.getDMRModeHang();
|
||||
|
||||
if (txHang > m_rfModeHang)
|
||||
txHang = m_rfModeHang;
|
||||
if (txHang > m_netModeHang)
|
||||
txHang = m_netModeHang;
|
||||
if (txHang > m_dmrRFModeHang)
|
||||
txHang = m_dmrRFModeHang;
|
||||
|
||||
if (m_conf.getDMRNetworkEnabled()) {
|
||||
if (txHang > m_dmrNetModeHang)
|
||||
txHang = m_dmrNetModeHang;
|
||||
}
|
||||
|
||||
if (callHang > txHang)
|
||||
callHang = txHang;
|
||||
|
||||
LogInfo("DMR Parameters");
|
||||
LogInfo("DMR RF Parameters");
|
||||
LogInfo(" Id: %u", id);
|
||||
LogInfo(" Color Code: %u", colorCode);
|
||||
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
||||
|
@ -390,6 +413,7 @@ int CMMDVMHost::run()
|
|||
|
||||
LogInfo(" Call Hang: %us", callHang);
|
||||
LogInfo(" TX Hang: %us", txHang);
|
||||
LogInfo(" Mode Hang: %us", m_dmrRFModeHang);
|
||||
|
||||
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, embeddedLCOnly, dumpTAData, prefixes, blackList, whiteList, slot1TGWhiteList, slot2TGWhiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssi, jitter);
|
||||
|
||||
|
@ -400,24 +424,42 @@ int CMMDVMHost::run()
|
|||
if (m_ysfEnabled) {
|
||||
bool lowDeviation = m_conf.getFusionLowDeviation();
|
||||
bool remoteGateway = m_conf.getFusionRemoteGateway();
|
||||
bool selfOnly = m_conf.getFusionSelfOnly();
|
||||
bool sqlEnabled = m_conf.getFusionSQLEnabled();
|
||||
unsigned char sql = m_conf.getFusionSQL();
|
||||
m_ysfRFModeHang = m_conf.getFusionModeHang();
|
||||
|
||||
LogInfo("YSF Parameters");
|
||||
LogInfo("YSF RF Parameters");
|
||||
LogInfo(" Low Deviation: %s", lowDeviation ? "yes" : "no");
|
||||
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");
|
||||
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
||||
LogInfo(" DSQ: %s", sqlEnabled ? "yes" : "no");
|
||||
if (sqlEnabled)
|
||||
LogInfo(" DSQ Value: %u", sql);
|
||||
LogInfo(" Mode Hang: %us", m_ysfRFModeHang);
|
||||
|
||||
ysf = new CYSFControl(m_callsign, m_ysfNetwork, m_display, m_timeout, m_duplex, lowDeviation, remoteGateway, rssi);
|
||||
ysf = new CYSFControl(m_callsign, selfOnly, m_ysfNetwork, m_display, m_timeout, m_duplex, lowDeviation, remoteGateway, rssi);
|
||||
ysf->setSQL(sqlEnabled, sql);
|
||||
}
|
||||
|
||||
CP25Control* p25 = NULL;
|
||||
if (m_p25Enabled) {
|
||||
unsigned int id = m_conf.getP25Id();
|
||||
unsigned int nac = m_conf.getP25NAC();
|
||||
bool uidOverride = m_conf.getP25OverrideUID();
|
||||
bool selfOnly = m_conf.getP25SelfOnly();
|
||||
bool remoteGateway = m_conf.getP25RemoteGateway();
|
||||
m_p25RFModeHang = m_conf.getP25ModeHang();
|
||||
|
||||
LogInfo("P25 Parameters");
|
||||
LogInfo("P25 RF Parameters");
|
||||
LogInfo(" Id: %u", id);
|
||||
LogInfo(" NAC: $%03X", nac);
|
||||
LogInfo(" UID Override: %s", uidOverride ? "yes" : "no");
|
||||
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
||||
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");
|
||||
LogInfo(" Mode Hang: %us", m_p25RFModeHang);
|
||||
|
||||
p25 = new CP25Control(nac, uidOverride, m_p25Network, m_display, m_timeout, m_duplex, m_lookup, rssi);
|
||||
p25 = new CP25Control(nac, id, selfOnly, uidOverride, m_p25Network, m_display, m_timeout, m_duplex, m_lookup, remoteGateway, rssi);
|
||||
}
|
||||
|
||||
setMode(MODE_IDLE);
|
||||
|
@ -456,7 +498,7 @@ int CMMDVMHost::run()
|
|||
if (m_mode == MODE_IDLE) {
|
||||
bool ret = dstar->writeModem(data, len);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_dstarRFModeHang);
|
||||
setMode(MODE_DSTAR);
|
||||
}
|
||||
} else if (m_mode == MODE_DSTAR) {
|
||||
|
@ -473,12 +515,12 @@ int CMMDVMHost::run()
|
|||
if (m_duplex) {
|
||||
bool ret = dmr->processWakeup(data);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_dmrRFModeHang);
|
||||
setMode(MODE_DMR);
|
||||
dmrBeaconTimer.stop();
|
||||
}
|
||||
} else {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_dmrRFModeHang);
|
||||
setMode(MODE_DMR);
|
||||
dmr->writeModemSlot1(data, len);
|
||||
dmrBeaconTimer.stop();
|
||||
|
@ -510,12 +552,12 @@ int CMMDVMHost::run()
|
|||
if (m_duplex) {
|
||||
bool ret = dmr->processWakeup(data);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_dmrRFModeHang);
|
||||
setMode(MODE_DMR);
|
||||
dmrBeaconTimer.stop();
|
||||
}
|
||||
} else {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_dmrRFModeHang);
|
||||
setMode(MODE_DMR);
|
||||
dmr->writeModemSlot2(data, len);
|
||||
dmrBeaconTimer.stop();
|
||||
|
@ -546,7 +588,7 @@ int CMMDVMHost::run()
|
|||
if (m_mode == MODE_IDLE) {
|
||||
bool ret = ysf->writeModem(data, len);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_ysfRFModeHang);
|
||||
setMode(MODE_YSF);
|
||||
}
|
||||
} else if (m_mode == MODE_YSF) {
|
||||
|
@ -562,7 +604,7 @@ int CMMDVMHost::run()
|
|||
if (m_mode == MODE_IDLE) {
|
||||
bool ret = p25->writeModem(data, len);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_rfModeHang);
|
||||
m_modeTimer.setTimeout(m_p25RFModeHang);
|
||||
setMode(MODE_P25);
|
||||
}
|
||||
} else if (m_mode == MODE_P25) {
|
||||
|
@ -582,7 +624,7 @@ int CMMDVMHost::run()
|
|||
len = dstar->readModem(data);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_netModeHang);
|
||||
m_modeTimer.setTimeout(m_dstarNetModeHang);
|
||||
setMode(MODE_DSTAR);
|
||||
}
|
||||
if (m_mode == MODE_DSTAR) {
|
||||
|
@ -601,7 +643,7 @@ int CMMDVMHost::run()
|
|||
len = dmr->readModemSlot1(data);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_netModeHang);
|
||||
m_modeTimer.setTimeout(m_dmrNetModeHang);
|
||||
setMode(MODE_DMR);
|
||||
}
|
||||
if (m_mode == MODE_DMR) {
|
||||
|
@ -623,7 +665,7 @@ int CMMDVMHost::run()
|
|||
len = dmr->readModemSlot2(data);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_netModeHang);
|
||||
m_modeTimer.setTimeout(m_dmrNetModeHang);
|
||||
setMode(MODE_DMR);
|
||||
}
|
||||
if (m_mode == MODE_DMR) {
|
||||
|
@ -647,7 +689,7 @@ int CMMDVMHost::run()
|
|||
len = ysf->readModem(data);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_netModeHang);
|
||||
m_modeTimer.setTimeout(m_ysfNetModeHang);
|
||||
setMode(MODE_YSF);
|
||||
}
|
||||
if (m_mode == MODE_YSF) {
|
||||
|
@ -666,14 +708,13 @@ int CMMDVMHost::run()
|
|||
len = p25->readModem(data);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_netModeHang);
|
||||
m_modeTimer.setTimeout(m_p25NetModeHang);
|
||||
setMode(MODE_P25);
|
||||
}
|
||||
if (m_mode == MODE_P25) {
|
||||
m_modem->writeP25Data(data, len);
|
||||
m_modeTimer.start();
|
||||
}
|
||||
else if (m_mode != MODE_LOCKOUT) {
|
||||
} else if (m_mode != MODE_LOCKOUT) {
|
||||
LogWarning("P25 data received when in mode %u", m_mode);
|
||||
}
|
||||
}
|
||||
|
@ -745,8 +786,6 @@ int CMMDVMHost::run()
|
|||
CThread::sleep(5U);
|
||||
}
|
||||
|
||||
LogMessage("MMDVMHost-%s is exiting on receipt of SIGHUP1", VERSION);
|
||||
|
||||
setMode(MODE_IDLE);
|
||||
|
||||
m_modem->close();
|
||||
|
@ -799,18 +838,22 @@ bool CMMDVMHost::createModem()
|
|||
bool pttInvert = m_conf.getModemPTTInvert();
|
||||
unsigned int txDelay = m_conf.getModemTXDelay();
|
||||
unsigned int dmrDelay = m_conf.getModemDMRDelay();
|
||||
unsigned int rxLevel = m_conf.getModemRXLevel();
|
||||
unsigned int cwIdTXLevel = m_conf.getModemCWIdTXLevel();
|
||||
unsigned int dstarTXLevel = m_conf.getModemDStarTXLevel();
|
||||
unsigned int dmrTXLevel = m_conf.getModemDMRTXLevel();
|
||||
unsigned int ysfTXLevel = m_conf.getModemYSFTXLevel();
|
||||
unsigned int p25TXLevel = m_conf.getModemP25TXLevel();
|
||||
float rxLevel = m_conf.getModemRXLevel();
|
||||
float cwIdTXLevel = m_conf.getModemCWIdTXLevel();
|
||||
float dstarTXLevel = m_conf.getModemDStarTXLevel();
|
||||
float dmrTXLevel = m_conf.getModemDMRTXLevel();
|
||||
float ysfTXLevel = m_conf.getModemYSFTXLevel();
|
||||
float p25TXLevel = m_conf.getModemP25TXLevel();
|
||||
bool trace = m_conf.getModemTrace();
|
||||
bool debug = m_conf.getModemDebug();
|
||||
unsigned int colorCode = m_conf.getDMRColorCode();
|
||||
bool lowDeviation = m_conf.getFusionLowDeviation();
|
||||
unsigned int rxFrequency = m_conf.getRxFrequency();
|
||||
unsigned int txFrequency = m_conf.getTxFrequency();
|
||||
unsigned int rxFrequency = m_conf.getRXFrequency();
|
||||
unsigned int txFrequency = m_conf.getTXFrequency();
|
||||
int rxOffset = m_conf.getModemRXOffset();
|
||||
int txOffset = m_conf.getModemTXOffset();
|
||||
int rxDCOffset = m_conf.getModemRXDCOffset();
|
||||
int txDCOffset = m_conf.getModemTXDCOffset();
|
||||
|
||||
LogInfo("Modem Parameters");
|
||||
LogInfo(" Port: %s", port.c_str());
|
||||
|
@ -818,20 +861,24 @@ bool CMMDVMHost::createModem()
|
|||
LogInfo(" TX Invert: %s", txInvert ? "yes" : "no");
|
||||
LogInfo(" PTT Invert: %s", pttInvert ? "yes" : "no");
|
||||
LogInfo(" TX Delay: %ums", txDelay);
|
||||
LogInfo(" RX Offset: %dHz", rxOffset);
|
||||
LogInfo(" TX Offset: %dHz", txOffset);
|
||||
LogInfo(" RX DC Offset: %d", rxDCOffset);
|
||||
LogInfo(" TX DC Offset: %d", txDCOffset);
|
||||
LogInfo(" DMR Delay: %u (%.1fms)", dmrDelay, float(dmrDelay) * 0.0416666F);
|
||||
LogInfo(" RX Level: %u%%", rxLevel);
|
||||
LogInfo(" CW Id TX Level: %u%%", cwIdTXLevel);
|
||||
LogInfo(" D-Star TX Level: %u%%", dstarTXLevel);
|
||||
LogInfo(" DMR TX Level: %u%%", dmrTXLevel);
|
||||
LogInfo(" YSF TX Level: %u%%", ysfTXLevel);
|
||||
LogInfo(" P25 TX Level: %u%%", p25TXLevel);
|
||||
LogInfo(" RX Frequency: %uHz", rxFrequency);
|
||||
LogInfo(" TX Frequency: %uHz", txFrequency);
|
||||
LogInfo(" RX Level: %.1f%%", rxLevel);
|
||||
LogInfo(" CW Id TX Level: %.1f%%", cwIdTXLevel);
|
||||
LogInfo(" D-Star TX Level: %.1f%%", dstarTXLevel);
|
||||
LogInfo(" DMR TX Level: %.1f%%", dmrTXLevel);
|
||||
LogInfo(" YSF TX Level: %.1f%%", ysfTXLevel);
|
||||
LogInfo(" P25 TX Level: %.1f%%", p25TXLevel);
|
||||
LogInfo(" RX Frequency: %uHz (%uHz)", rxFrequency, rxFrequency + rxOffset);
|
||||
LogInfo(" TX Frequency: %uHz (%uHz)", txFrequency, txFrequency + txOffset);
|
||||
|
||||
m_modem = new CModem(port, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, trace, debug);
|
||||
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled);
|
||||
m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel);
|
||||
m_modem->setRFParams(rxFrequency, txFrequency);
|
||||
m_modem->setRFParams(rxFrequency, rxOffset, txFrequency, txOffset, txDCOffset, rxDCOffset);
|
||||
m_modem->setDMRParams(colorCode);
|
||||
m_modem->setYSFParams(lowDeviation);
|
||||
|
||||
|
@ -851,11 +898,13 @@ bool CMMDVMHost::createDStarNetwork()
|
|||
unsigned int gatewayPort = m_conf.getDStarGatewayPort();
|
||||
unsigned int localPort = m_conf.getDStarLocalPort();
|
||||
bool debug = m_conf.getDStarNetworkDebug();
|
||||
m_dstarNetModeHang = m_conf.getDStarNetworkModeHang();
|
||||
|
||||
LogInfo("D-Star Network Parameters");
|
||||
LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
|
||||
LogInfo(" Gateway Port: %u", gatewayPort);
|
||||
LogInfo(" Local Port: %u", localPort);
|
||||
LogInfo(" Mode Hang: %us", m_dstarNetModeHang);
|
||||
|
||||
m_dstarNetwork = new CDStarNetwork(gatewayAddress, gatewayPort, localPort, m_duplex, VERSION, debug);
|
||||
|
||||
|
@ -883,6 +932,7 @@ bool CMMDVMHost::createDMRNetwork()
|
|||
bool slot1 = m_conf.getDMRNetworkSlot1();
|
||||
bool slot2 = m_conf.getDMRNetworkSlot2();
|
||||
HW_TYPE hwType = m_modem->getHWType();
|
||||
m_dmrNetModeHang = m_conf.getDMRNetworkModeHang();
|
||||
|
||||
LogInfo("DMR Network Parameters");
|
||||
LogInfo(" Address: %s", address.c_str());
|
||||
|
@ -894,6 +944,7 @@ bool CMMDVMHost::createDMRNetwork()
|
|||
LogInfo(" Jitter: %ums", jitter);
|
||||
LogInfo(" Slot 1: %s", slot1 ? "enabled" : "disabled");
|
||||
LogInfo(" Slot 2: %s", slot2 ? "enabled" : "disabled");
|
||||
LogInfo(" Mode Hang: %us", m_dmrNetModeHang);
|
||||
|
||||
m_dmrNetwork = new CDMRNetwork(address, port, local, id, password, m_duplex, VERSION, debug, slot1, slot2, hwType);
|
||||
|
||||
|
@ -903,8 +954,8 @@ bool CMMDVMHost::createDMRNetwork()
|
|||
m_dmrNetwork->setOptions(options);
|
||||
}
|
||||
|
||||
unsigned int rxFrequency = m_conf.getRxFrequency();
|
||||
unsigned int txFrequency = m_conf.getTxFrequency();
|
||||
unsigned int rxFrequency = m_conf.getRXFrequency();
|
||||
unsigned int txFrequency = m_conf.getTXFrequency();
|
||||
unsigned int power = m_conf.getPower();
|
||||
unsigned int colorCode = m_conf.getDMRColorCode();
|
||||
float latitude = m_conf.getLatitude();
|
||||
|
@ -944,17 +995,19 @@ bool CMMDVMHost::createYSFNetwork()
|
|||
{
|
||||
std::string myAddress = m_conf.getFusionNetworkMyAddress();
|
||||
unsigned int myPort = m_conf.getFusionNetworkMyPort();
|
||||
std::string gwyAddress = m_conf.getFusionNetworkGwyAddress();
|
||||
unsigned int gwyPort = m_conf.getFusionNetworkGwyPort();
|
||||
std::string gatewayAddress = m_conf.getFusionNetworkGatewayAddress();
|
||||
unsigned int gatewayPort = m_conf.getFusionNetworkGatewayPort();
|
||||
m_ysfNetModeHang = m_conf.getFusionNetworkModeHang();
|
||||
bool debug = m_conf.getFusionNetworkDebug();
|
||||
|
||||
LogInfo("System Fusion Network Parameters");
|
||||
LogInfo(" Local Address: %s", myAddress.c_str());
|
||||
LogInfo(" Local Port: %u", myPort);
|
||||
LogInfo(" Gateway Address: %s", gwyAddress.c_str());
|
||||
LogInfo(" Gateway Port: %u", gwyPort);
|
||||
LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
|
||||
LogInfo(" Gateway Port: %u", gatewayPort);
|
||||
LogInfo(" Mode Hang: %us", m_ysfNetModeHang);
|
||||
|
||||
m_ysfNetwork = new CYSFNetwork(myAddress, myPort, gwyAddress, gwyPort, m_callsign, debug);
|
||||
m_ysfNetwork = new CYSFNetwork(myAddress, myPort, gatewayAddress, gatewayPort, m_callsign, debug);
|
||||
|
||||
bool ret = m_ysfNetwork->open();
|
||||
if (!ret) {
|
||||
|
@ -973,12 +1026,14 @@ bool CMMDVMHost::createP25Network()
|
|||
std::string gatewayAddress = m_conf.getP25GatewayAddress();
|
||||
unsigned int gatewayPort = m_conf.getP25GatewayPort();
|
||||
unsigned int localPort = m_conf.getP25LocalPort();
|
||||
m_p25NetModeHang = m_conf.getP25NetworkModeHang();
|
||||
bool debug = m_conf.getP25NetworkDebug();
|
||||
|
||||
LogInfo("P25 Network Parameters");
|
||||
LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
|
||||
LogInfo(" Gateway Port: %u", gatewayPort);
|
||||
LogInfo(" Local Port: %u", localPort);
|
||||
LogInfo(" Mode Hang: %us", m_p25NetModeHang);
|
||||
|
||||
m_p25Network = new CP25Network(gatewayAddress, gatewayPort, localPort, debug);
|
||||
|
||||
|
@ -1002,17 +1057,14 @@ void CMMDVMHost::readParams()
|
|||
m_p25Enabled = m_conf.getP25Enabled();
|
||||
m_duplex = m_conf.getDuplex();
|
||||
m_callsign = m_conf.getCallsign();
|
||||
m_id = m_conf.getId();
|
||||
m_timeout = m_conf.getTimeout();
|
||||
|
||||
m_rfModeHang = m_conf.getRFModeHang();
|
||||
m_netModeHang = m_conf.getNetModeHang();
|
||||
|
||||
LogInfo("General Parameters");
|
||||
LogInfo(" Callsign: %s", m_callsign.c_str());
|
||||
LogInfo(" Id: %u", m_id);
|
||||
LogInfo(" Duplex: %s", m_duplex ? "yes" : "no");
|
||||
LogInfo(" Timeout: %us", m_timeout);
|
||||
LogInfo(" RF Mode Hang: %us", m_rfModeHang);
|
||||
LogInfo(" Net Mode Hang: %us", m_netModeHang);
|
||||
LogInfo(" D-Star: %s", m_dstarEnabled ? "enabled" : "disabled");
|
||||
LogInfo(" DMR: %s", m_dmrEnabled ? "enabled" : "disabled");
|
||||
LogInfo(" YSF: %s", m_ysfEnabled ? "enabled" : "disabled");
|
||||
|
@ -1047,6 +1099,7 @@ void CMMDVMHost::createDisplay()
|
|||
bool displayClock = m_conf.getNextionDisplayClock();
|
||||
bool utc = m_conf.getNextionUTC();
|
||||
unsigned int idleBrightness = m_conf.getNextionIdleBrightness();
|
||||
unsigned int screenLayout = m_conf.getNextionScreenLayout();
|
||||
|
||||
LogInfo(" Port: %s", port.c_str());
|
||||
LogInfo(" Brightness: %u", brightness);
|
||||
|
@ -1055,15 +1108,27 @@ void CMMDVMHost::createDisplay()
|
|||
LogInfo(" Display UTC: %s", utc ? "yes" : "no");
|
||||
LogInfo(" Idle Brightness: %u", idleBrightness);
|
||||
|
||||
switch (screenLayout) {
|
||||
case 0U:
|
||||
LogInfo(" Screen Layout: G4KLX (Default)");
|
||||
break;
|
||||
case 2U:
|
||||
LogInfo(" Screen Layout: ON7LDS");
|
||||
break;
|
||||
default:
|
||||
LogInfo(" Screen Layout: %u (Unknown)", screenLayout);
|
||||
break;
|
||||
}
|
||||
|
||||
if (port == "modem") {
|
||||
ISerialPort* serial = new CModemSerialPort(m_modem);
|
||||
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness);
|
||||
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout);
|
||||
} else if (port == "ump") {
|
||||
if (m_ump != NULL)
|
||||
m_display = new CNextion(m_callsign, dmrid, m_ump, brightness, displayClock, utc, idleBrightness);
|
||||
m_display = new CNextion(m_callsign, dmrid, m_ump, brightness, displayClock, utc, idleBrightness, screenLayout);
|
||||
} else {
|
||||
ISerialPort* serial = new CSerialController(port, SERIAL_9600);
|
||||
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness);
|
||||
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout);
|
||||
}
|
||||
} else if (type == "LCDproc") {
|
||||
std::string address = m_conf.getLCDprocAddress();
|
||||
|
@ -1131,7 +1196,8 @@ void CMMDVMHost::createDisplay()
|
|||
unsigned char type = m_conf.getOLEDType();
|
||||
unsigned char brightness = m_conf.getOLEDBrightness();
|
||||
bool invert = m_conf.getOLEDInvert();
|
||||
m_display = new COLED(type, brightness, invert);
|
||||
bool scroll = m_conf.getOLEDScroll();
|
||||
m_display = new COLED(type, brightness, invert, scroll);
|
||||
#endif
|
||||
} else {
|
||||
m_display = new CNullDisplay;
|
||||
|
|
11
MMDVMHost.h
11
MMDVMHost.h
|
@ -50,8 +50,14 @@ private:
|
|||
CDisplay* m_display;
|
||||
CUMP* m_ump;
|
||||
unsigned char m_mode;
|
||||
unsigned int m_rfModeHang;
|
||||
unsigned int m_netModeHang;
|
||||
unsigned int m_dstarRFModeHang;
|
||||
unsigned int m_dmrRFModeHang;
|
||||
unsigned int m_ysfRFModeHang;
|
||||
unsigned int m_p25RFModeHang;
|
||||
unsigned int m_dstarNetModeHang;
|
||||
unsigned int m_dmrNetModeHang;
|
||||
unsigned int m_ysfNetModeHang;
|
||||
unsigned int m_p25NetModeHang;
|
||||
CTimer m_modeTimer;
|
||||
CTimer m_dmrTXTimer;
|
||||
CTimer m_cwIdTimer;
|
||||
|
@ -64,6 +70,7 @@ private:
|
|||
unsigned int m_cwIdTime;
|
||||
CDMRLookup* m_lookup;
|
||||
std::string m_callsign;
|
||||
unsigned int m_id;
|
||||
std::string m_cwCallsign;
|
||||
|
||||
void readParams();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
|
@ -22,32 +22,32 @@
|
|||
<ProjectGuid>{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>MMDVMHost</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
@ -183,12 +183,14 @@
|
|||
<ClInclude Include="Golay24128.h" />
|
||||
<ClInclude Include="Hamming.h" />
|
||||
<ClInclude Include="DMRLookup.h" />
|
||||
<ClInclude Include="JitterBuffer.h" />
|
||||
<ClInclude Include="LCDproc.h" />
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="MMDVMHost.h" />
|
||||
<ClInclude Include="Modem.h" />
|
||||
<ClInclude Include="ModemSerialPort.h" />
|
||||
<ClInclude Include="Mutex.h" />
|
||||
<ClInclude Include="NetworkInfo.h" />
|
||||
<ClInclude Include="Nextion.h" />
|
||||
<ClInclude Include="NullDisplay.h" />
|
||||
<ClInclude Include="P25Audio.h" />
|
||||
|
@ -252,12 +254,14 @@
|
|||
<ClCompile Include="Golay2087.cpp" />
|
||||
<ClCompile Include="Golay24128.cpp" />
|
||||
<ClCompile Include="Hamming.cpp" />
|
||||
<ClCompile Include="JitterBuffer.cpp" />
|
||||
<ClCompile Include="LCDproc.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="MMDVMHost.cpp" />
|
||||
<ClCompile Include="Modem.cpp" />
|
||||
<ClCompile Include="ModemSerialPort.cpp" />
|
||||
<ClCompile Include="Mutex.cpp" />
|
||||
<ClCompile Include="NetworkInfo.cpp" />
|
||||
<ClCompile Include="Nextion.cpp" />
|
||||
<ClCompile Include="NullDisplay.cpp" />
|
||||
<ClCompile Include="P25Audio.cpp" />
|
||||
|
|
|
@ -221,6 +221,12 @@
|
|||
<ClInclude Include="RSSIInterpolator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NetworkInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JitterBuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BPTC19696.cpp">
|
||||
|
@ -412,5 +418,11 @@
|
|||
<ClCompile Include="RSSIInterpolator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NetworkInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JitterBuffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
6
Makefile
6
Makefile
|
@ -9,9 +9,9 @@ LDFLAGS = -g
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
||||
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
||||
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o P25Control.o \
|
||||
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o \
|
||||
Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ LDFLAGS = -g -L/usr/local/lib
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
||||
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
||||
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o P25Control.o \
|
||||
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o \
|
||||
Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ LDFLAGS = -g -L/usr/local/lib
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o \
|
||||
P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o \
|
||||
TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \
|
||||
P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \
|
||||
StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ LDFLAGS = -g -L/usr/local/lib
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
||||
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
||||
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \
|
||||
P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \
|
||||
StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ LDFLAGS = -g -L/usr/local/lib
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
||||
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
||||
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o JitterBuffer.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \
|
||||
P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \
|
||||
SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ LDFLAGS = -g -L/usr/local/lib
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
||||
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
||||
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \
|
||||
P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \
|
||||
StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ LDFLAGS = -g
|
|||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
|
||||
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
|
||||
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
||||
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
||||
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o P25Control.o \
|
||||
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o \
|
||||
Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
41
Modem.cpp
41
Modem.cpp
|
@ -107,6 +107,8 @@ m_dstarEnabled(false),
|
|||
m_dmrEnabled(false),
|
||||
m_ysfEnabled(false),
|
||||
m_p25Enabled(false),
|
||||
m_rxDCOffset(0),
|
||||
m_txDCOffset(0),
|
||||
m_serial(port, SERIAL_115200, true),
|
||||
m_buffer(NULL),
|
||||
m_length(0U),
|
||||
|
@ -145,10 +147,12 @@ CModem::~CModem()
|
|||
delete[] m_buffer;
|
||||
}
|
||||
|
||||
void CModem::setRFParams(unsigned int rxFrequency, unsigned int txFrequency)
|
||||
void CModem::setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset)
|
||||
{
|
||||
m_rxFrequency = rxFrequency;
|
||||
m_txFrequency = txFrequency;
|
||||
m_rxFrequency = rxFrequency + rxOffset;
|
||||
m_txFrequency = txFrequency + txOffset;
|
||||
m_txDCOffset = txDCOffset;
|
||||
m_rxDCOffset = rxDCOffset;
|
||||
}
|
||||
|
||||
void CModem::setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled)
|
||||
|
@ -159,7 +163,7 @@ void CModem::setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled,
|
|||
m_p25Enabled = p25Enabled;
|
||||
}
|
||||
|
||||
void CModem::setLevels(unsigned int rxLevel, unsigned int cwIdTXLevel, unsigned int dstarTXLevel, unsigned int dmrTXLevel, unsigned int ysfTXLevel, unsigned int p25TXLevel)
|
||||
void CModem::setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel)
|
||||
{
|
||||
m_rxLevel = rxLevel;
|
||||
m_cwIdTXLevel = cwIdTXLevel;
|
||||
|
@ -902,6 +906,10 @@ bool CModem::readVersion()
|
|||
if (ret != 3)
|
||||
return false;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
m_serial.setNonblock(true);
|
||||
#endif
|
||||
|
||||
for (unsigned int count = 0U; count < MAX_RESPONSES; count++) {
|
||||
CThread::sleep(10U);
|
||||
RESP_TYPE_MMDVM resp = getResponse();
|
||||
|
@ -910,6 +918,8 @@ bool CModem::readVersion()
|
|||
m_hwType = HWT_MMDVM;
|
||||
else if (::memcmp(m_buffer + 4U, "DVMEGA", 6U) == 0)
|
||||
m_hwType = HWT_DVMEGA;
|
||||
else if (::memcmp(m_buffer + 4U, "ZUMspot", 7U) == 0)
|
||||
m_hwType = HWT_MMDVM_HS;
|
||||
|
||||
LogInfo("MMDVM protocol version: %u, description: %.*s", m_buffer[3U], m_length - 4U, m_buffer + 4U);
|
||||
return true;
|
||||
|
@ -943,7 +953,7 @@ bool CModem::setConfig()
|
|||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
|
||||
buffer[1U] = 16U;
|
||||
buffer[1U] = 18U;
|
||||
|
||||
buffer[2U] = MMDVM_SET_CONFIG;
|
||||
|
||||
|
@ -975,9 +985,9 @@ bool CModem::setConfig()
|
|||
|
||||
buffer[6U] = MODE_IDLE;
|
||||
|
||||
buffer[7U] = (m_rxLevel * 255U) / 100U;
|
||||
buffer[7U] = (unsigned char)(m_rxLevel * 2.55F + 0.5F);
|
||||
|
||||
buffer[8U] = (m_cwIdTXLevel * 255U) / 100U;
|
||||
buffer[8U] = (unsigned char)(m_cwIdTXLevel * 2.55F + 0.5F);
|
||||
|
||||
buffer[9U] = m_dmrColorCode;
|
||||
|
||||
|
@ -985,15 +995,18 @@ bool CModem::setConfig()
|
|||
|
||||
buffer[11U] = 128U; // Was OscOffset
|
||||
|
||||
buffer[12U] = (m_dstarTXLevel * 255U) / 100U;
|
||||
buffer[13U] = (m_dmrTXLevel * 255U) / 100U;
|
||||
buffer[14U] = (m_ysfTXLevel * 255U) / 100U;
|
||||
buffer[15U] = (m_p25TXLevel * 255U) / 100U;
|
||||
buffer[12U] = (unsigned char)(m_dstarTXLevel * 2.55F + 0.5F);
|
||||
buffer[13U] = (unsigned char)(m_dmrTXLevel * 2.55F + 0.5F);
|
||||
buffer[14U] = (unsigned char)(m_ysfTXLevel * 2.55F + 0.5F);
|
||||
buffer[15U] = (unsigned char)(m_p25TXLevel * 2.55F + 0.5F);
|
||||
|
||||
// CUtils::dump(1U, "Written", buffer, 16U);
|
||||
buffer[16U] = (unsigned char)(m_txDCOffset + 128);
|
||||
buffer[17U] = (unsigned char)(m_rxDCOffset + 128);
|
||||
|
||||
int ret = m_serial.write(buffer, 16U);
|
||||
if (ret != 16)
|
||||
// CUtils::dump(1U, "Written", buffer, 18U);
|
||||
|
||||
int ret = m_serial.write(buffer, 18U);
|
||||
if (ret != 18)
|
||||
return false;
|
||||
|
||||
unsigned int count = 0U;
|
||||
|
|
18
Modem.h
18
Modem.h
|
@ -37,9 +37,9 @@ public:
|
|||
CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug);
|
||||
~CModem();
|
||||
|
||||
void setRFParams(unsigned int rxFrequency, unsigned int txFrequency);
|
||||
void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset);
|
||||
void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled);
|
||||
void setLevels(unsigned int rxLevel, unsigned int cwIdTXLevel, unsigned int dstarTXLevel, unsigned int dmrTXLevel, unsigned int ysfTXLevel, unsigned int p25Enabled);
|
||||
void setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25Enabled);
|
||||
void setDMRParams(unsigned int colorCode);
|
||||
void setYSFParams(bool loDev);
|
||||
|
||||
|
@ -97,12 +97,12 @@ private:
|
|||
bool m_pttInvert;
|
||||
unsigned int m_txDelay;
|
||||
unsigned int m_dmrDelay;
|
||||
unsigned int m_rxLevel;
|
||||
unsigned int m_cwIdTXLevel;
|
||||
unsigned int m_dstarTXLevel;
|
||||
unsigned int m_dmrTXLevel;
|
||||
unsigned int m_ysfTXLevel;
|
||||
unsigned int m_p25TXLevel;
|
||||
float m_rxLevel;
|
||||
float m_cwIdTXLevel;
|
||||
float m_dstarTXLevel;
|
||||
float m_dmrTXLevel;
|
||||
float m_ysfTXLevel;
|
||||
float m_p25TXLevel;
|
||||
bool m_trace;
|
||||
bool m_debug;
|
||||
unsigned int m_rxFrequency;
|
||||
|
@ -111,6 +111,8 @@ private:
|
|||
bool m_dmrEnabled;
|
||||
bool m_ysfEnabled;
|
||||
bool m_p25Enabled;
|
||||
int m_rxDCOffset;
|
||||
int m_txDCOffset;
|
||||
CSerialController m_serial;
|
||||
unsigned char* m_buffer;
|
||||
unsigned int m_length;
|
||||
|
|
222
NetworkInfo.cpp
Normal file
222
NetworkInfo.cpp
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright (C) 2017 by Lieven De Samblanx ON7LDS
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "NetworkInfo.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <clocale>
|
||||
|
||||
#include <sys/types.h>
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#ifndef NO_ERROR
|
||||
#define NO_ERROR 0
|
||||
#endif
|
||||
#ifndef ERROR_BUFFER_OVERFLOW
|
||||
#define ERROR_BUFFER_OVERFLOW 111
|
||||
#endif
|
||||
#ifndef ERROR_INSUFFICIENT_BUFFER
|
||||
#define ERROR_INSUFFICIENT_BUFFER 122
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CNetworkInfo::CNetworkInfo()
|
||||
{
|
||||
}
|
||||
|
||||
CNetworkInfo::~CNetworkInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void CNetworkInfo::getNetworkInterface(unsigned char* info)
|
||||
{
|
||||
LogInfo("Interfaces Info");
|
||||
|
||||
::strcpy((char*)info, "(address unknown)");
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
const unsigned int IFLISTSIZ = 25U;
|
||||
|
||||
FILE* fp = ::fopen("/proc/net/route" , "r");
|
||||
if (fp == NULL) {
|
||||
LogError("Unabled to open /proc/route");
|
||||
return;
|
||||
}
|
||||
|
||||
char* dflt = NULL;
|
||||
|
||||
char line[100U];
|
||||
while (::fgets(line, 100U, fp)) {
|
||||
char* p1 = strtok(line , " \t");
|
||||
char* p2 = strtok(NULL , " \t");
|
||||
|
||||
if (p1 != NULL && p2 != NULL) {
|
||||
if (::strcmp(p2, "00000000") == 0) {
|
||||
dflt = p1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
|
||||
if (dflt == NULL) {
|
||||
LogError("Unable to find the default route");
|
||||
return;
|
||||
}
|
||||
|
||||
char interfacelist[IFLISTSIZ][50+INET6_ADDRSTRLEN];
|
||||
for (unsigned int n = 0U; n < IFLISTSIZ; n++)
|
||||
interfacelist[n][0] = 0;
|
||||
|
||||
struct ifaddrs* ifaddr;
|
||||
if (::getifaddrs(&ifaddr) == -1) {
|
||||
LogError("getifaddrs failure");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int ifnr = 0U;
|
||||
for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
int family = ifa->ifa_addr->sa_family;
|
||||
if (family == AF_INET || family == AF_INET6) {
|
||||
char host[NI_MAXHOST];
|
||||
int s = ::getnameinfo(ifa->ifa_addr, family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
||||
if (s != 0) {
|
||||
LogError("getnameinfo() failed: %s\n", gai_strerror(s));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (family == AF_INET) {
|
||||
::sprintf(interfacelist[ifnr], "%s: %s", ifa->ifa_name, host);
|
||||
LogInfo(" IPv4: %s", interfacelist[ifnr]);
|
||||
} else {
|
||||
::sprintf(interfacelist[ifnr], "%s: %s", ifa->ifa_name, host);
|
||||
LogInfo(" IPv6: %s", interfacelist[ifnr]);
|
||||
}
|
||||
|
||||
ifnr++;
|
||||
}
|
||||
}
|
||||
|
||||
::freeifaddrs(ifaddr);
|
||||
|
||||
LogInfo(" Default interface is : %s" , dflt);
|
||||
|
||||
for (unsigned int n = 0U; n < ifnr; n++) {
|
||||
char* p = ::strchr(interfacelist[n], '%');
|
||||
if (p != NULL)
|
||||
*p = 0;
|
||||
|
||||
if (::strstr(interfacelist[n], dflt) != 0) {
|
||||
::strcpy((char*)info, interfacelist[n]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo(" IP to show: %s", info);
|
||||
#else
|
||||
PMIB_IPFORWARDTABLE pIpForwardTable = (MIB_IPFORWARDTABLE *)::malloc(sizeof(MIB_IPFORWARDTABLE));
|
||||
if (pIpForwardTable == NULL) {
|
||||
LogError("Error allocating memory");
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwSize = 0U;
|
||||
if (::GetIpForwardTable(pIpForwardTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
|
||||
::free(pIpForwardTable);
|
||||
pIpForwardTable = (MIB_IPFORWARDTABLE *)::malloc(dwSize);
|
||||
if (pIpForwardTable == NULL) {
|
||||
LogError("Error allocating memory");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD ret = ::GetIpForwardTable(pIpForwardTable, &dwSize, 0);
|
||||
if (ret != NO_ERROR) {
|
||||
::free(pIpForwardTable);
|
||||
LogError("GetIpForwardTable failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD found = 999U;
|
||||
for (DWORD i = 0U; i < pIpForwardTable->dwNumEntries; i++) {
|
||||
if (pIpForwardTable->table[i].dwForwardDest == 0U) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == 999U) {
|
||||
::free(pIpForwardTable);
|
||||
LogError("Unable to find the default destination in the routing table.");
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD ifnr = pIpForwardTable->table[found].dwForwardIfIndex;
|
||||
::free(pIpForwardTable);
|
||||
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)::malloc(sizeof(IP_ADAPTER_INFO));
|
||||
if (pAdapterInfo == NULL) {
|
||||
LogError("Error allocating memory");
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG buflen = sizeof(IP_ADAPTER_INFO);
|
||||
if (::GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
|
||||
::free(pAdapterInfo);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *)::malloc(buflen);
|
||||
if (pAdapterInfo == NULL) {
|
||||
LogError("Error allocating memory");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (::GetAdaptersInfo(pAdapterInfo, &buflen) != NO_ERROR) {
|
||||
::free(pAdapterInfo);
|
||||
LogError("Call to GetAdaptersInfo failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter != NULL) {
|
||||
LogInfo(" IP : %s", pAdapter->IpAddressList.IpAddress.String);
|
||||
if (pAdapter->Index == ifnr)
|
||||
::strcpy((char*)info, pAdapter->IpAddressList.IpAddress.String);
|
||||
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
|
||||
::free(pAdapterInfo);
|
||||
|
||||
LogInfo(" IP to show: %s", info);
|
||||
#endif
|
||||
}
|
32
NetworkInfo.h
Normal file
32
NetworkInfo.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2017 by Lieven De Samblanx ON7LDS
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(NETWORKINFO_H)
|
||||
#define NETWORKINFO_H
|
||||
|
||||
class CNetworkInfo {
|
||||
public:
|
||||
CNetworkInfo();
|
||||
~CNetworkInfo();
|
||||
|
||||
void getNetworkInterface(unsigned char* info);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
111
Nextion.cpp
111
Nextion.cpp
|
@ -16,6 +16,7 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "NetworkInfo.h"
|
||||
#include "Nextion.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
@ -24,6 +25,7 @@
|
|||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <clocale>
|
||||
//#include <unistd.h>
|
||||
|
||||
const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms
|
||||
const unsigned int DSTAR_BER_COUNT = 63U; // 63 * 20ms = 1260ms
|
||||
|
@ -34,9 +36,10 @@ const unsigned int YSF_BER_COUNT = 13U; // 13 * 100ms = 1300ms
|
|||
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||
const unsigned int P25_BER_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||
|
||||
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness) :
|
||||
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout) :
|
||||
CDisplay(),
|
||||
m_callsign(callsign),
|
||||
m_ipaddress("(ip unknown)"),
|
||||
m_dmrid(dmrid),
|
||||
m_serial(serial),
|
||||
m_brightness(brightness),
|
||||
|
@ -44,6 +47,7 @@ m_mode(MODE_IDLE),
|
|||
m_displayClock(displayClock),
|
||||
m_utc(utc),
|
||||
m_idleBrightness(idleBrightness),
|
||||
m_screenLayout(screenLayout),
|
||||
m_clockDisplayTimer(1000U, 0U, 400U),
|
||||
m_rssiAccum1(0U),
|
||||
m_rssiAccum2(0U),
|
||||
|
@ -64,6 +68,9 @@ CNextion::~CNextion()
|
|||
|
||||
bool CNextion::open()
|
||||
{
|
||||
unsigned char info[100U];
|
||||
CNetworkInfo* m_network;
|
||||
|
||||
bool ret = m_serial->open();
|
||||
if (!ret) {
|
||||
LogError("Cannot open the port for the Nextion display");
|
||||
|
@ -71,6 +78,11 @@ bool CNextion::open()
|
|||
return false;
|
||||
}
|
||||
|
||||
info[0]=0;
|
||||
m_network = new CNetworkInfo;
|
||||
m_network->getNetworkInterface(info);
|
||||
m_ipaddress = (char*)info;
|
||||
|
||||
sendCommand("bkcmd=0");
|
||||
|
||||
setIdle();
|
||||
|
@ -78,19 +90,23 @@ bool CNextion::open()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CNextion::setIdleInt()
|
||||
{
|
||||
sendCommand("page MMDVM");
|
||||
|
||||
char command[30];
|
||||
char command[30U];
|
||||
::sprintf(command, "dim=%u", m_idleBrightness);
|
||||
sendCommand(command);
|
||||
|
||||
::sprintf(command, "t0.txt=\"%-6s / %u\"", m_callsign.c_str(), m_dmrid);
|
||||
|
||||
::sprintf(command, "t0.txt=\"%s/%u\"", m_callsign.c_str(), m_dmrid);
|
||||
sendCommand(command);
|
||||
|
||||
sendCommand("t1.txt=\"MMDVM IDLE\"");
|
||||
|
||||
::sprintf(command, "t3.txt=\"%s\"", m_ipaddress.c_str());
|
||||
sendCommand(command);
|
||||
|
||||
m_clockDisplayTimer.start();
|
||||
|
||||
m_mode = MODE_IDLE;
|
||||
|
@ -226,11 +242,22 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
if (m_mode != MODE_DMR) {
|
||||
sendCommand("page DMR");
|
||||
|
||||
if (slotNo == 1U)
|
||||
if (slotNo == 1U) {
|
||||
if (m_screenLayout == 2U) {
|
||||
sendCommand("t2.pco=0");
|
||||
sendCommand("t2.font=4");
|
||||
}
|
||||
|
||||
sendCommand("t2.txt=\"2 Listening\"");
|
||||
else
|
||||
} else {
|
||||
if (m_screenLayout == 2U) {
|
||||
sendCommand("t0.pco=0");
|
||||
sendCommand("t0.font=4");
|
||||
}
|
||||
|
||||
sendCommand("t0.txt=\"1 Listening\"");
|
||||
}
|
||||
}
|
||||
|
||||
char text[30U];
|
||||
::sprintf(text, "dim=%u", m_brightness);
|
||||
|
@ -238,12 +265,24 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
|
||||
if (slotNo == 1U) {
|
||||
::sprintf(text, "t0.txt=\"1 %s %s\"", type, src.c_str());
|
||||
|
||||
if (m_screenLayout == 2U) {
|
||||
sendCommand("t0.pco=0");
|
||||
sendCommand("t0.font=4");
|
||||
}
|
||||
|
||||
sendCommand(text);
|
||||
|
||||
::sprintf(text, "t1.txt=\"%s%s\"", group ? "TG" : "", dst.c_str());
|
||||
sendCommand(text);
|
||||
} else {
|
||||
::sprintf(text, "t2.txt=\"2 %s %s\"", type, src.c_str());
|
||||
|
||||
if (m_screenLayout == 2U) {
|
||||
sendCommand("t2.pco=0");
|
||||
sendCommand("t2.font=4");
|
||||
}
|
||||
|
||||
sendCommand(text);
|
||||
|
||||
::sprintf(text, "t3.txt=\"%s%s\"", group ? "TG" : "", dst.c_str());
|
||||
|
@ -306,6 +345,52 @@ void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
|||
}
|
||||
}
|
||||
|
||||
void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
|
||||
{
|
||||
if (m_screenLayout < 2U)
|
||||
return;
|
||||
|
||||
if (type[0] == ' ') {
|
||||
if (slotNo == 1U)
|
||||
sendCommand("t0.pco=33808");
|
||||
else
|
||||
sendCommand("t2.pco=33808");
|
||||
return;
|
||||
}
|
||||
|
||||
if (slotNo == 1U) {
|
||||
char text[40U];
|
||||
::sprintf(text, "t0.txt=\"1 %s %s\"", type, talkerAlias);
|
||||
|
||||
if (m_screenLayout == 2U) {
|
||||
if (::strlen((char*)talkerAlias) > (16U-4U))
|
||||
sendCommand("t0.font=3");
|
||||
if (::strlen((char*)talkerAlias) > (20U-4U))
|
||||
sendCommand("t0.font=2");
|
||||
if (::strlen((char*)talkerAlias) > (24U-4U))
|
||||
sendCommand("t0.font=1");
|
||||
}
|
||||
|
||||
sendCommand("t0.pco=1024");
|
||||
sendCommand(text);
|
||||
} else {
|
||||
char text[40U];
|
||||
::sprintf(text, "t2.txt=\"2 %s %s\"", type, talkerAlias);
|
||||
|
||||
if (m_screenLayout == 2U) {
|
||||
if (::strlen((char*)talkerAlias) > (16U-4U))
|
||||
sendCommand("t2.font=3");
|
||||
if (::strlen((char*)talkerAlias) > (20U-4U))
|
||||
sendCommand("t2.font=2");
|
||||
if (::strlen((char*)talkerAlias) > (24U-4U))
|
||||
sendCommand("t2.font=1");
|
||||
}
|
||||
|
||||
sendCommand("t2.pco=1024");
|
||||
sendCommand(text);
|
||||
}
|
||||
}
|
||||
|
||||
void CNextion::writeDMRBERInt(unsigned int slotNo, float ber)
|
||||
{
|
||||
if (slotNo == 1U) {
|
||||
|
@ -353,11 +438,23 @@ void CNextion::clearDMRInt(unsigned int slotNo)
|
|||
{
|
||||
if (slotNo == 1U) {
|
||||
sendCommand("t0.txt=\"1 Listening\"");
|
||||
|
||||
if (m_screenLayout == 2U) {
|
||||
sendCommand("t0.pco=0");
|
||||
sendCommand("t0.font=4");
|
||||
}
|
||||
|
||||
sendCommand("t1.txt=\"\"");
|
||||
sendCommand("t4.txt=\"\"");
|
||||
sendCommand("t6.txt=\"\"");
|
||||
} else {
|
||||
sendCommand("t2.txt=\"2 Listening\"");
|
||||
|
||||
if (m_screenLayout == 2U) {
|
||||
sendCommand("t2.pco=0");
|
||||
sendCommand("t2.font=4");
|
||||
}
|
||||
|
||||
sendCommand("t3.txt=\"\"");
|
||||
sendCommand("t5.txt=\"\"");
|
||||
sendCommand("t7.txt=\"\"");
|
||||
|
@ -568,6 +665,8 @@ void CNextion::clockInt(unsigned int ms)
|
|||
|
||||
void CNextion::close()
|
||||
{
|
||||
sendCommand("page MMDVM");
|
||||
sendCommand("t1.txt=\"MMDVM STOPPED\"");
|
||||
m_serial->close();
|
||||
delete m_serial;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
class CNextion : public CDisplay
|
||||
{
|
||||
public:
|
||||
CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness);
|
||||
CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout);
|
||||
virtual ~CNextion();
|
||||
|
||||
virtual bool open();
|
||||
|
@ -48,6 +48,7 @@ protected:
|
|||
|
||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
||||
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
||||
virtual void clearDMRInt(unsigned int slotNo);
|
||||
|
||||
|
@ -68,6 +69,7 @@ protected:
|
|||
|
||||
private:
|
||||
std::string m_callsign;
|
||||
std::string m_ipaddress;
|
||||
unsigned int m_dmrid;
|
||||
ISerialPort* m_serial;
|
||||
unsigned int m_brightness;
|
||||
|
@ -75,6 +77,7 @@ private:
|
|||
bool m_displayClock;
|
||||
bool m_utc;
|
||||
unsigned int m_idleBrightness;
|
||||
unsigned int m_screenLayout;
|
||||
CTimer m_clockDisplayTimer;
|
||||
unsigned int m_rssiAccum1;
|
||||
unsigned int m_rssiAccum2;
|
||||
|
|
BIN
Nextion_DB2OE/NX3224K024.HMI
Normal file
BIN
Nextion_DB2OE/NX3224K024.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224K024.tft
Normal file
BIN
Nextion_DB2OE/NX3224K024.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224K028.HMI
Normal file
BIN
Nextion_DB2OE/NX3224K028.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224K028.tft
Normal file
BIN
Nextion_DB2OE/NX3224K028.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224T024.HMI
Normal file
BIN
Nextion_DB2OE/NX3224T024.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224T024.tft
Normal file
BIN
Nextion_DB2OE/NX3224T024.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224T028.HMI
Normal file
BIN
Nextion_DB2OE/NX3224T028.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX3224T028.tft
Normal file
BIN
Nextion_DB2OE/NX3224T028.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4024K032.HMI
Normal file
BIN
Nextion_DB2OE/NX4024K032.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4024K032.tft
Normal file
BIN
Nextion_DB2OE/NX4024K032.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4024T032.HMI
Normal file
BIN
Nextion_DB2OE/NX4024T032.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4024T032.tft
Normal file
BIN
Nextion_DB2OE/NX4024T032.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4827K043.HMI
Normal file
BIN
Nextion_DB2OE/NX4827K043.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4827K043.tft
Normal file
BIN
Nextion_DB2OE/NX4827K043.tft
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4827T043.HMI
Normal file
BIN
Nextion_DB2OE/NX4827T043.HMI
Normal file
Binary file not shown.
BIN
Nextion_DB2OE/NX4827T043.tft
Normal file
BIN
Nextion_DB2OE/NX4827T043.tft
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX3224T024-L2.HMI
Normal file
BIN
Nextion_ON7LDS/NX3224T024-L2.HMI
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX3224T024-L2.tft
Normal file
BIN
Nextion_ON7LDS/NX3224T024-L2.tft
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX3224T028-L2.HMI
Normal file
BIN
Nextion_ON7LDS/NX3224T028-L2.HMI
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX3224T028-L2.tft
Normal file
BIN
Nextion_ON7LDS/NX3224T028-L2.tft
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX4024T032-L2.HMI
Normal file
BIN
Nextion_ON7LDS/NX4024T032-L2.HMI
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX4024T032-L2.tft
Normal file
BIN
Nextion_ON7LDS/NX4024T032-L2.tft
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX4832T035-L2.HMI
Normal file
BIN
Nextion_ON7LDS/NX4832T035-L2.HMI
Normal file
Binary file not shown.
BIN
Nextion_ON7LDS/NX4832T035-L2.tft
Normal file
BIN
Nextion_ON7LDS/NX4832T035-L2.tft
Normal file
Binary file not shown.
29
Nextion_ON7LDS/README
Normal file
29
Nextion_ON7LDS/README
Normal file
|
@ -0,0 +1,29 @@
|
|||
The files in this directory are Nextion screen layouts with better fonts than
|
||||
the(rather ugly) standard Nextion fonts
|
||||
|
||||
There are some other changes:
|
||||
|
||||
* On the main screen there is a field to display the active ip address of the
|
||||
device. On Linux it is preceded with the network interface name.
|
||||
* DMR: if received, the Talker Alias is decoded and displayed. The TA will be
|
||||
in green, so the user knows it is a decoded TA displaying.
|
||||
This happens on-the-fly: as the parts of the TA arrive, they will immediately
|
||||
be shown.
|
||||
* If you want to change my screen layout, the only thing to keep in mind is
|
||||
that the MMDVMHost program will select following font numbers:
|
||||
default font for the TA field : font 4
|
||||
TA >16 characters : font 3
|
||||
TA >20 characters : font 2
|
||||
TA >24 characters : font 1
|
||||
There always have to be at least 5 fonts, of which font 1-4 are used for the
|
||||
TA. If your display is wide enough to show all characters in one font, you
|
||||
must copy this font to the lesser ('smaller') fonts.
|
||||
i.e. : the 3.2" the display can show more than 31 characters (the maximum
|
||||
TA length) in font 2, so this font is also copied to font 1.
|
||||
* The screenlayout has to be selected with the parameter ScreenLayout in the
|
||||
MMDVM.ini file under the Nextion section. This way, the extra function
|
||||
to automatically change the font size, is activated.
|
||||
0 = auto (future use, for now it's G4KLX layout)
|
||||
1 = G4KLX layout
|
||||
2 = ON7LDS layout
|
||||
|
308
OLED.cpp
308
OLED.cpp
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,68 +18,96 @@
|
|||
|
||||
#include "OLED.h"
|
||||
|
||||
//Logo MMDVM for Idle Screen
|
||||
static unsigned char logo_glcd_bmp[] =
|
||||
{ 0b00101011, 0b11010100,
|
||||
0b01010111, 0b11101010,
|
||||
0b01010111, 0b11101010,
|
||||
0b00101011, 0b11010100,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000001, 0b10000000,
|
||||
0b00000000, 0b00000000 };
|
||||
|
||||
//DMR 48x16 px
|
||||
static unsigned char logo_dmr_bmp[] =
|
||||
{ 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10111111, 0b11111000, 0b01111000, 0b00011110, 0b01111111, 0b11100001,
|
||||
0b10111111, 0b11111110, 0b01111100, 0b00111110, 0b01100000, 0b00011001,
|
||||
0b10110000, 0b00001110, 0b01100110, 0b01100110, 0b01100000, 0b00011001,
|
||||
0b10110000, 0b00000110, 0b01100011, 0b11000110, 0b01100000, 0b00011001,
|
||||
0b10110000, 0b00000110, 0b01100001, 0b10000110, 0b01100000, 0b00011001,
|
||||
0b10110000, 0b00000110, 0b01100000, 0b00000110, 0b01111111, 0b11111001,
|
||||
0b10110000, 0b00000110, 0b01100000, 0b00000110, 0b01111000, 0b00000001,
|
||||
0b10110000, 0b00000110, 0b01100000, 0b00000110, 0b01101100, 0b00000001,
|
||||
0b10110000, 0b00000110, 0b01100000, 0b00000110, 0b01100110, 0b00000001,
|
||||
0b10110000, 0b00001110, 0b01100000, 0b00000110, 0b01100011, 0b00000001,
|
||||
0b10111111, 0b11111110, 0b01100000, 0b00000110, 0b01100001, 0b10000001,
|
||||
0b10011111, 0b11111000, 0b01100000, 0b00000110, 0b01100000, 0b11000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xF8, 0x03, 0xFC, 0x7F, 0x80, 0x3F, 0xC7, 0xFF, 0xFC, 0xF8, 0x00, 0xF9, 0xFC, 0x01, 0xFE,
|
||||
0x01, 0xFC, 0x07, 0xFC, 0x7F, 0xC0, 0x7F, 0xC4, 0x00, 0x02, 0x48, 0x00, 0x91, 0xFE, 0x03, 0xFE,
|
||||
0x03, 0xFC, 0x07, 0xFC, 0x7F, 0xC0, 0x7F, 0xC5, 0xFF, 0xF1, 0x24, 0x01, 0x23, 0xFE, 0x03, 0xFE,
|
||||
0x03, 0xFE, 0x0F, 0xBC, 0x7B, 0xE0, 0xFB, 0xC5, 0x00, 0x09, 0x24, 0x01, 0x23, 0xDF, 0x07, 0xDE,
|
||||
0x07, 0xDE, 0x0F, 0x3C, 0x79, 0xE0, 0xF3, 0xC5, 0x00, 0x05, 0x12, 0x02, 0x47, 0xCF, 0x07, 0x9E,
|
||||
0x07, 0x9F, 0x1F, 0x3C, 0x79, 0xF1, 0xF3, 0xC5, 0x00, 0x05, 0x12, 0x02, 0x47, 0x8F, 0x8F, 0x9E,
|
||||
0x0F, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC5, 0x00, 0x05, 0x09, 0x04, 0x8F, 0x87, 0x8F, 0x1E,
|
||||
0x0F, 0x0F, 0xBE, 0x3C, 0x78, 0xFB, 0xE3, 0xC5, 0x00, 0x05, 0x09, 0x04, 0x8F, 0x07, 0xDF, 0x1E,
|
||||
0x1F, 0x07, 0xFC, 0x3C, 0x78, 0x7F, 0xC3, 0xC5, 0x00, 0x05, 0x04, 0x89, 0x1F, 0x03, 0xFE, 0x1E,
|
||||
0x1E, 0x03, 0xFC, 0x3C, 0x78, 0x7F, 0xC3, 0xC5, 0x00, 0x09, 0x04, 0x89, 0x1E, 0x01, 0xFE, 0x1E,
|
||||
0x3E, 0x03, 0xF8, 0x3C, 0x78, 0x3F, 0x83, 0xC5, 0xFF, 0xF1, 0x02, 0x72, 0x3E, 0x01, 0xFC, 0x1E,
|
||||
0x3C, 0x01, 0xF0, 0x3C, 0x78, 0x1F, 0x03, 0xC4, 0x00, 0x02, 0x02, 0x02, 0x3C, 0x00, 0xF8, 0x1E,
|
||||
0x7C, 0x01, 0xF0, 0x3C, 0x78, 0x1F, 0x03, 0xC7, 0xFF, 0xFC, 0x01, 0xFC, 0x7C, 0x00, 0xF8, 0x1E,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
//D-Star 64x16 px
|
||||
//Logo D-Star 128x16 px
|
||||
static unsigned char logo_dstar_bmp[] =
|
||||
{ 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10000001, 0b11111100, 0b00000000, 0b00111100, 0b00000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000010, 0b01000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000000, 0b01000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000000, 0b01000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b01111111, 0b00111100, 0b01111000, 0b00111100, 0b00111100, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b00000010, 0b01000000, 0b00000010, 0b01000010, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b00000010, 0b01000000, 0b00111110, 0b01000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b00000010, 0b01000000, 0b01000010, 0b01000000, 0b00000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000010, 0b01000010, 0b01000010, 0b01000000, 0b01000001,
|
||||
0b10000001, 0b11111100, 0b00000000, 0b00111100, 0b00111100, 0b00111100, 0b01000000, 0b01000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111
|
||||
{
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x60, 0x03, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xF0, 0xFF, 0xFE, 0x07, 0x80, 0x3F, 0xF8,
|
||||
0x00, 0x00, 0xC0, 0x07, 0xC1, 0xE0, 0x00, 0x00, 0x78, 0x7C, 0xFF, 0xFE, 0x0F, 0xC0, 0x3F, 0xFC,
|
||||
0x00, 0x01, 0xC0, 0x07, 0x80, 0xF0, 0x00, 0x00, 0xE0, 0x3C, 0x07, 0x80, 0x0F, 0xC0, 0x78, 0x0E,
|
||||
0x00, 0x03, 0xC0, 0x07, 0x80, 0x70, 0x00, 0x00, 0xE0, 0x38, 0x07, 0x00, 0x1B, 0xC0, 0x78, 0x0E,
|
||||
0x00, 0x07, 0xC0, 0x07, 0x80, 0x70, 0x00, 0x01, 0xE0, 0x00, 0x07, 0x00, 0x33, 0xC0, 0x70, 0x1E,
|
||||
0x07, 0xFF, 0xFE, 0x07, 0x00, 0x70, 0x00, 0x01, 0xF8, 0x00, 0x07, 0x00, 0x63, 0xC0, 0x70, 0x3C,
|
||||
0x01, 0xFF, 0xF8, 0x0F, 0x00, 0x71, 0xFF, 0xE0, 0xFF, 0xF0, 0x0E, 0x00, 0xE1, 0xE0, 0xFF, 0xE0,
|
||||
0x00, 0x7F, 0xE0, 0x0F, 0x00, 0x60, 0x00, 0x00, 0x03, 0xF8, 0x0E, 0x00, 0xC1, 0xE0, 0xFF, 0xE0,
|
||||
0x00, 0x3F, 0x80, 0x0E, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x0E, 0x01, 0xFF, 0xE0, 0xE0, 0x70,
|
||||
0x00, 0x7F, 0x00, 0x1E, 0x00, 0xE0, 0x00, 0x03, 0x80, 0x70, 0x0C, 0x03, 0xFC, 0xE0, 0xE0, 0x30,
|
||||
0x00, 0xFF, 0x00, 0x1E, 0x01, 0xC0, 0x00, 0x07, 0x80, 0xE0, 0x1C, 0x07, 0x00, 0xE1, 0xE0, 0x38,
|
||||
0x01, 0xEF, 0x00, 0x1C, 0x07, 0x80, 0x00, 0x07, 0xC1, 0xE0, 0x1C, 0x06, 0x00, 0xF1, 0xC0, 0x38,
|
||||
0x03, 0x87, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x1C, 0x0C, 0x00, 0xF3, 0xC0, 0x38,
|
||||
0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
COLED::COLED(unsigned char displayType, unsigned char displayBrightness, bool displayInvert) :
|
||||
//Logo DMR 128x16 px
|
||||
static unsigned char logo_dmr_bmp[] =
|
||||
{
|
||||
0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xF8, 0x00, 0x00, 0x1F, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xFC, 0x00, 0x00, 0x3F, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE1, 0xFE, 0x00, 0x00, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x0F, 0xF1, 0xFF, 0x80, 0x01, 0xFF, 0x1F, 0x80, 0x00, 0x1F, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x03, 0xF9, 0xFF, 0xC0, 0x03, 0xFF, 0x1F, 0x80, 0x00, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x01, 0xF9, 0xFF, 0xE0, 0x07, 0xFF, 0x1F, 0x80, 0x00, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x01, 0xFD, 0xF3, 0xF0, 0x1F, 0x9F, 0x1F, 0x80, 0x00, 0x1F, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x00, 0xFD, 0xF1, 0xFC, 0x3F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x00, 0xFD, 0xF0, 0xFE, 0x7E, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x01, 0xFD, 0xF0, 0x7F, 0xFC, 0x1F, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x01, 0xF9, 0xF0, 0x1F, 0xF0, 0x1F, 0x1F, 0x81, 0xFC, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x07, 0xF9, 0xF0, 0x0F, 0xE0, 0x1F, 0x1F, 0x80, 0x7F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0xF8, 0x00, 0x3F, 0xF1, 0xF0, 0x07, 0xC0, 0x1F, 0x1F, 0x80, 0x3F, 0xC0, 0x00, 0x00,
|
||||
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xC1, 0xF0, 0x03, 0x80, 0x1F, 0x1F, 0x80, 0x0F, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0xF0, 0x00, 0x00, 0x1F, 0x1F, 0x80, 0x03, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x01, 0xF0, 0x00, 0x00, 0x1F, 0x1F, 0x80, 0x01, 0xFF, 0x00, 0x00
|
||||
};
|
||||
|
||||
//Logo Fusion 128x16
|
||||
const unsigned char logo_fusion_bmp [] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xFC, 0x00, 0x1F, 0xE1, 0xFE, 0x1F, 0xFF, 0xF8, 0x7F, 0xC3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE,
|
||||
0x03, 0xFC, 0x00, 0x3F, 0xC3, 0xFC, 0x3F, 0x80, 0x00, 0x7F, 0x87, 0xF0, 0xFF, 0x0F, 0xF1, 0xFF,
|
||||
0x07, 0xFF, 0xFC, 0x7F, 0x83, 0xF8, 0x7F, 0x80, 0x00, 0xFF, 0x0F, 0xF0, 0xFF, 0x1F, 0xE1, 0xFE,
|
||||
0x0F, 0xFF, 0xF0, 0x7F, 0x07, 0xF0, 0xFF, 0xFF, 0xC1, 0xFF, 0x1F, 0xE1, 0xFE, 0x3F, 0xC3, 0xFC,
|
||||
0x0F, 0xF0, 0x00, 0xFE, 0x0F, 0xE0, 0x7F, 0xFF, 0xE1, 0xFE, 0x3F, 0xC3, 0xFC, 0x3F, 0xC3, 0xFC,
|
||||
0x1F, 0xE0, 0x01, 0xFC, 0x1F, 0xE0, 0x1F, 0xFF, 0xE3, 0xFC, 0x3F, 0xC3, 0xF8, 0x7F, 0x87, 0xF8,
|
||||
0x3F, 0xC0, 0x03, 0xFC, 0x3F, 0xC0, 0x00, 0x3F, 0xC7, 0xF8, 0x7F, 0x87, 0xF8, 0xFF, 0x0F, 0xF0,
|
||||
0x7F, 0xC0, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0x07, 0xF8, 0x7F, 0xCF, 0xE1, 0xFF, 0x1F, 0xF8,
|
||||
0x7F, 0x80, 0x01, 0xFF, 0xFF, 0xC7, 0xFF, 0xFC, 0x0F, 0xF0, 0x3F, 0xFF, 0x81, 0xFE, 0x1F, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
|
||||
COLED::COLED(unsigned char displayType, unsigned char displayBrightness, bool displayInvert, bool displayScroll) :
|
||||
m_displayType(displayType),
|
||||
m_displayBrightness(displayBrightness),
|
||||
m_displayInvert(displayInvert)
|
||||
m_displayInvert(displayInvert),
|
||||
m_displayScroll(displayScroll)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -127,12 +155,14 @@ void COLED::setIdleInt()
|
|||
|
||||
display.clearDisplay();
|
||||
OLED_statusbar();
|
||||
display.setCursor(0,display.height()/2);
|
||||
display.setTextSize(2);
|
||||
display.print("Idle");
|
||||
display.setTextSize(1);
|
||||
|
||||
// display.setCursor(0,30);
|
||||
// display.setTextSize(3);
|
||||
// display.print("Idle");
|
||||
|
||||
// display.setTextSize(1);
|
||||
display.startscrolldiagright(0x00,0x0f); //the MMDVM logo scrolls the whole screen
|
||||
display.display();
|
||||
display.startscrollright(0x02,0x0f);
|
||||
}
|
||||
|
||||
void COLED::setErrorInt(const char* text)
|
||||
|
@ -141,8 +171,10 @@ void COLED::setErrorInt(const char* text)
|
|||
|
||||
display.clearDisplay();
|
||||
OLED_statusbar();
|
||||
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.printf("%s\n",text);
|
||||
|
||||
display.display();
|
||||
}
|
||||
|
||||
|
@ -152,35 +184,42 @@ void COLED::setLockoutInt()
|
|||
|
||||
display.clearDisplay();
|
||||
OLED_statusbar();
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
|
||||
display.setCursor(0,30);
|
||||
display.setTextSize(3);
|
||||
display.print("Lockout");
|
||||
|
||||
display.setTextSize(1);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
||||
{
|
||||
m_mode = MODE_DSTAR;
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.printf("%s %.8s/%4.4s", type, my1, my2);
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
|
||||
display.clearDisplay();
|
||||
display.fillRect(0,OLED_LINE1,display.width(),display.height(),BLACK); //clear everything beneath logo
|
||||
|
||||
display.setCursor(0,OLED_LINE2);
|
||||
display.printf("via %.8s", reflector);
|
||||
display.fillRect(0, OLED_LINE3, display.width(), 10, BLACK);
|
||||
display.printf("%s %.8s/%4.4s",type,my1,my2);
|
||||
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.printf("%.8s <- %-8s", your, reflector);
|
||||
display.printf("-> %.8s",your);
|
||||
|
||||
display.setCursor(0,OLED_LINE5);
|
||||
display.printf("via %.8s",reflector);
|
||||
|
||||
OLED_statusbar();
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::clearDStarInt()
|
||||
{
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.fillRect(0,OLED_LINE1, display.width(),display.height(),BLACK); //clear everything beneath the logo
|
||||
|
||||
display.setCursor(40,38);
|
||||
display.print("Listening");
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
display.fillRect(0, OLED_LINE3, display.width(), 10, BLACK);
|
||||
OLED_statusbar();
|
||||
|
||||
display.display();
|
||||
}
|
||||
|
||||
|
@ -188,115 +227,128 @@ void COLED::writeDMRInt(unsigned int slotNo, const std::string& src, bool group,
|
|||
{
|
||||
|
||||
if (m_mode != MODE_DMR) {
|
||||
|
||||
display.clearDisplay();
|
||||
|
||||
m_mode = MODE_DMR;
|
||||
|
||||
if (slotNo == 1U)
|
||||
{
|
||||
display.fillRect(0, OLED_LINE3, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.fillRect(0,OLED_LINE4,display.width(),20,BLACK); //20=> clear 2 lines
|
||||
display.setCursor(0,OLED_LINE4);
|
||||
display.print("2 Listening");
|
||||
display.fillRect(0, OLED_LINE4, display.width(), 10, BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.fillRect(0,OLED_LINE2,display.width(),20,BLACK); //20=> clear 2 lines
|
||||
display.setCursor(0,OLED_LINE2);
|
||||
display.print("1 Listening");
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (slotNo == 1U) {
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.printf("%i %s %s", slotNo, type, src.c_str());
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
if (slotNo == 1U)
|
||||
{
|
||||
display.fillRect(0,OLED_LINE2,display.width(),20,BLACK);
|
||||
display.setCursor(0,OLED_LINE2);
|
||||
display.printf("%s%s", group ? "TG" : "", dst.c_str());
|
||||
} else {
|
||||
display.fillRect(0, OLED_LINE3, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.printf("%i %s %s",slotNo,type,src.c_str());
|
||||
display.fillRect(0, OLED_LINE4, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE4);
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.printf("%s%s",group ? "TG" : "",dst.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
display.fillRect(0,OLED_LINE4,display.width(),20,BLACK);
|
||||
display.setCursor(0,OLED_LINE4);
|
||||
display.printf("%i %s %s",slotNo,type,src.c_str());
|
||||
display.setCursor(0,OLED_LINE5);
|
||||
display.printf("%s%s", group ? "TG" : "", dst.c_str());
|
||||
}
|
||||
|
||||
OLED_statusbar();
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::clearDMRInt(unsigned int slotNo)
|
||||
{
|
||||
OLED_statusbar();
|
||||
if (slotNo == 1U)
|
||||
{
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 20, BLACK);
|
||||
display.setCursor(0,OLED_LINE2);
|
||||
display.print("1 Listening");
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.fillRect(0, OLED_LINE3, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.fillRect(0, OLED_LINE4, display.width(), 20, BLACK);
|
||||
display.setCursor(0, OLED_LINE4);
|
||||
display.print("2 Listening");
|
||||
display.fillRect(0, OLED_LINE4, display.width(), 10, BLACK);
|
||||
}
|
||||
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::writeFusionInt(const char* source, const char* dest, const char* type, const char* origin)
|
||||
{
|
||||
|
||||
m_mode = MODE_YSF;
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.printf("%s %.10s", type, source);
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
|
||||
display.clearDisplay();
|
||||
display.fillRect(0,OLED_LINE1,display.width(),display.height(),BLACK);
|
||||
|
||||
display.setCursor(0,OLED_LINE2);
|
||||
display.printf("%s %.10s", type, source);
|
||||
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.printf(" %.10s", dest);
|
||||
|
||||
OLED_statusbar();
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::clearFusionInt()
|
||||
{
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.fillRect(0, OLED_LINE1, display.width(), display.height(), BLACK);
|
||||
|
||||
display.setCursor(40,38);
|
||||
display.print("Listening");
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
OLED_statusbar();
|
||||
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::writeP25Int(const char* source, bool group, unsigned int dest, const char* type)
|
||||
{
|
||||
m_mode = MODE_P25;
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.printf("%s %.10s", type, source);
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
|
||||
display.clearDisplay();
|
||||
display.fillRect(0, OLED_LINE1, display.width(), display.height(), BLACK);
|
||||
|
||||
display.setCursor(0,OLED_LINE2);
|
||||
display.printf("%s %.10s", type, source);
|
||||
|
||||
display.setCursor(0,OLED_LINE3);
|
||||
display.printf(" %s%u", group ? "TG" : "", dest);
|
||||
|
||||
OLED_statusbar();
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::clearP25Int()
|
||||
{
|
||||
display.fillRect(0, OLED_LINE1, display.width(), 10, BLACK);
|
||||
display.setCursor(0,OLED_LINE1);
|
||||
display.fillRect(0, OLED_LINE1, display.width(), display.height(), BLACK);
|
||||
|
||||
display.setCursor(40,38);
|
||||
display.print("Listening");
|
||||
display.fillRect(0, OLED_LINE2, display.width(), 10, BLACK);
|
||||
OLED_statusbar();
|
||||
|
||||
display.display();
|
||||
}
|
||||
|
||||
void COLED::writeCWInt()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0,display.height()/2);
|
||||
|
||||
display.setCursor(0,30);
|
||||
display.setTextSize(3);
|
||||
display.print("CW TX");
|
||||
|
||||
display.setTextSize(1);
|
||||
display.display();
|
||||
display.startscrollright(0x02,0x0f);
|
||||
|
@ -305,16 +357,26 @@ void COLED::writeCWInt()
|
|||
void COLED::clearCWInt()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0,display.height()/2);
|
||||
display.setTextSize(2);
|
||||
|
||||
display.setCursor(0,30);
|
||||
display.setTextSize(3);
|
||||
display.print("Idle");
|
||||
|
||||
display.setTextSize(1);
|
||||
display.display();
|
||||
display.startscrollright(0x02,0x0f);
|
||||
display.startscrollleft(0x02,0x0f);
|
||||
}
|
||||
|
||||
void COLED::close()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.fillRect(0, 0, display.width(), 16, BLACK);
|
||||
display.startscrollright(0x00,0x01);
|
||||
display.setCursor(0,00);
|
||||
display.setTextSize(2);
|
||||
display.print("-CLOSE-");
|
||||
display.display();
|
||||
|
||||
display.close();
|
||||
}
|
||||
|
||||
|
@ -323,15 +385,19 @@ void COLED::OLED_statusbar()
|
|||
display.stopscroll();
|
||||
display.fillRect(0, 0, display.width(), 16, BLACK);
|
||||
display.setTextColor(WHITE);
|
||||
|
||||
display.setCursor(0,0);
|
||||
if (m_mode == MODE_DMR)
|
||||
display.drawBitmap(0, 0, logo_dmr_bmp, 48, 16, WHITE);
|
||||
display.drawBitmap(0, 0, logo_dmr_bmp, 128, 16, WHITE);
|
||||
else if (m_mode == MODE_DSTAR)
|
||||
display.drawBitmap(0, 0, logo_dstar_bmp, 64, 16, WHITE);
|
||||
display.drawBitmap(0, 0, logo_dstar_bmp, 128, 16, WHITE);
|
||||
else if (m_mode == MODE_YSF)
|
||||
display.print("Fusion");
|
||||
display.drawBitmap(0, 0, logo_fusion_bmp, 128, 16, WHITE);
|
||||
else if (m_mode == MODE_P25)
|
||||
display.print("P25");
|
||||
else
|
||||
display.drawBitmap(0, 0, logo_glcd_bmp, 16, 15, WHITE);
|
||||
display.drawBitmap(0, 0, logo_glcd_bmp, 128, 16, WHITE);
|
||||
|
||||
if (m_displayScroll)
|
||||
display.startscrollright(0x00,0x02);
|
||||
}
|
||||
|
|
6
OLED.h
6
OLED.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,6 +24,7 @@
|
|||
#define OLED_LINE2 26
|
||||
#define OLED_LINE3 36
|
||||
#define OLED_LINE4 46
|
||||
#define OLED_LINE5 56
|
||||
|
||||
#include "Display.h"
|
||||
#include "Defines.h"
|
||||
|
@ -37,7 +38,7 @@
|
|||
class COLED : public CDisplay
|
||||
{
|
||||
public:
|
||||
COLED(unsigned char displayType, unsigned char displayBrighness, bool displayInvert);
|
||||
COLED(unsigned char displayType, unsigned char displayBrighness, bool displayInvert, bool displayScroll);
|
||||
virtual ~COLED();
|
||||
|
||||
virtual bool open();
|
||||
|
@ -71,6 +72,7 @@ private:
|
|||
unsigned char m_displayType;
|
||||
unsigned char m_displayBrightness;
|
||||
bool m_displayInvert;
|
||||
bool m_displayScroll;
|
||||
|
||||
ArduiPi_OLED display;
|
||||
void OLED_statusbar();
|
||||
|
|
|
@ -35,9 +35,12 @@ const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U
|
|||
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
CP25Control::CP25Control(unsigned int nac, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper) :
|
||||
CP25Control::CP25Control(unsigned int nac, unsigned int id, bool selfOnly, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, bool remoteGateway, CRSSIInterpolator* rssiMapper) :
|
||||
m_nac(nac),
|
||||
m_id(id),
|
||||
m_selfOnly(selfOnly),
|
||||
m_uidOverride(uidOverride),
|
||||
m_remoteGateway(remoteGateway),
|
||||
m_network(network),
|
||||
m_display(display),
|
||||
m_duplex(duplex),
|
||||
|
@ -101,14 +104,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
{
|
||||
assert(data != NULL);
|
||||
|
||||
// CUtils::dump(1U, "P25 Data", data, len);
|
||||
|
||||
bool sync = data[1U] == 0x01U;
|
||||
|
||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_LISTENING)
|
||||
return false;
|
||||
|
||||
if (data[0U] == TAG_LOST) {
|
||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
||||
if (m_rssi != 0U)
|
||||
LogMessage("P25, transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
else
|
||||
|
@ -128,6 +126,11 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (data[0U] == TAG_LOST) {
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sync && m_rfState == RS_RF_LISTENING)
|
||||
return false;
|
||||
|
||||
|
@ -177,12 +180,45 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
if (duid == P25_DUID_LDU1) {
|
||||
if (m_rfState == RS_RF_LISTENING) {
|
||||
m_rfData.reset();
|
||||
bool ret = m_rfData.decodeLDU1(data + 2U, m_network != NULL, m_uidOverride);
|
||||
bool ret = m_rfData.decodeLDU1(data + 2U);
|
||||
if (!ret) {
|
||||
m_lastDUID = duid;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int srcId = m_rfData.getSrcId();
|
||||
|
||||
if (m_selfOnly) {
|
||||
if (m_id > 99999999U) { // Check that the Config DMR-ID is bigger than 8 digits
|
||||
if (srcId != m_id / 100U)
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (m_id > 9999999U) { // Check that the Config DMR-ID is bigger than 7 digits
|
||||
if (srcId != m_id / 10U)
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (srcId != m_id) { // All other cases
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_uidOverride) {
|
||||
bool found = m_lookup->exists(srcId);
|
||||
if (!found)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
|
||||
unsigned int dstId = m_rfData.getDstId();
|
||||
std::string source = m_lookup->find(srcId);
|
||||
|
||||
LogMessage("P25, received RF transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||
m_display->writeP25(source.c_str(), grp, dstId, "R");
|
||||
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
|
||||
m_minRSSI = m_rssi;
|
||||
m_maxRSSI = m_rssi;
|
||||
m_aveRSSI = m_rssi;
|
||||
|
@ -190,10 +226,11 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
|
||||
createRFHeader();
|
||||
writeNetwork(data + 2U, P25_DUID_HEADER, false);
|
||||
} else {
|
||||
} else if (m_rfState == RS_RF_AUDIO) {
|
||||
writeNetwork(m_rfLDU, m_lastDUID, false);
|
||||
}
|
||||
|
||||
if (m_rfState == RS_RF_AUDIO) {
|
||||
// Regenerate Sync
|
||||
CSync::addP25Sync(data + 2U);
|
||||
|
||||
|
@ -232,21 +269,12 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
writeQueueRF(data, P25_LDU_FRAME_LENGTH_BYTES + 2U);
|
||||
}
|
||||
|
||||
if (m_rfState == RS_RF_LISTENING) {
|
||||
unsigned int srcId = m_rfData.getSrcId();
|
||||
bool grp = m_rfData.getLCF() == P25_LCF_GROUP;
|
||||
unsigned int dstId = m_rfData.getDstId();
|
||||
std::string source = m_lookup->find(srcId);
|
||||
LogMessage("P25, received RF transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||
m_display->writeP25(source.c_str(), grp, dstId, "R");
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
}
|
||||
|
||||
m_display->writeP25RSSI(m_rssi);
|
||||
} else if (duid == P25_DUID_LDU2) {
|
||||
if (m_rfState == RS_RF_LISTENING)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (duid == P25_DUID_LDU2) {
|
||||
if (m_rfState == RS_RF_AUDIO) {
|
||||
writeNetwork(m_rfLDU, m_lastDUID, false);
|
||||
|
||||
// Regenerate Sync
|
||||
|
@ -288,10 +316,11 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
}
|
||||
|
||||
m_display->writeP25RSSI(m_rssi);
|
||||
} else if (duid == P25_DUID_TERM || duid == P25_DUID_TERM_LC) {
|
||||
if (m_rfState == RS_RF_LISTENING)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (duid == P25_DUID_TERM || duid == P25_DUID_TERM_LC) {
|
||||
if (m_rfState == RS_RF_AUDIO) {
|
||||
writeNetwork(m_rfLDU, m_lastDUID, true);
|
||||
|
||||
::memset(data + 2U, 0x00U, P25_TERM_FRAME_LENGTH_BYTES);
|
||||
|
@ -328,11 +357,10 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
|||
data[1U] = 0x00U;
|
||||
writeQueueRF(data, P25_TERM_FRAME_LENGTH_BYTES + 2U);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int CP25Control::readModem(unsigned char* data)
|
||||
|
@ -725,6 +753,9 @@ void CP25Control::createNetHeader()
|
|||
m_netData.encodeHeader(buffer + 2U);
|
||||
|
||||
// Add busy bits
|
||||
if (m_remoteGateway)
|
||||
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, true, false);
|
||||
else
|
||||
addBusyBits(buffer + 2U, P25_HDR_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
writeQueueNet(buffer, P25_HDR_FRAME_LENGTH_BYTES + 2U);
|
||||
|
@ -766,6 +797,9 @@ void CP25Control::createNetLDU1()
|
|||
m_netLSD.encode(buffer + 2U);
|
||||
|
||||
// Add busy bits
|
||||
if (m_remoteGateway)
|
||||
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
|
||||
else
|
||||
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
writeQueueNet(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
|
||||
|
@ -811,6 +845,9 @@ void CP25Control::createNetLDU2()
|
|||
m_netLSD.encode(buffer + 2U);
|
||||
|
||||
// Add busy bits
|
||||
if (m_remoteGateway)
|
||||
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
|
||||
else
|
||||
addBusyBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
writeQueueNet(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
|
||||
|
@ -835,6 +872,9 @@ void CP25Control::createNetTerminator()
|
|||
m_nid.encode(buffer + 2U, P25_DUID_TERM);
|
||||
|
||||
// Add busy bits
|
||||
if (m_remoteGateway)
|
||||
addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, true, false);
|
||||
else
|
||||
addBusyBits(buffer + 2U, P25_TERM_FRAME_LENGTH_BITS, false, true);
|
||||
|
||||
writeQueueNet(buffer, P25_TERM_FRAME_LENGTH_BYTES + 2U);
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
class CP25Control {
|
||||
public:
|
||||
CP25Control(unsigned int nac, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper);
|
||||
CP25Control(unsigned int nac, unsigned int id, bool selfOly, bool uidOverride, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
||||
~CP25Control();
|
||||
|
||||
bool writeModem(unsigned char* data, unsigned int len);
|
||||
|
@ -47,7 +47,10 @@ public:
|
|||
|
||||
private:
|
||||
unsigned int m_nac;
|
||||
unsigned int m_id;
|
||||
bool m_selfOnly;
|
||||
bool m_uidOverride;
|
||||
bool m_remoteGateway;
|
||||
CP25Network* m_network;
|
||||
CDisplay* m_display;
|
||||
bool m_duplex;
|
||||
|
|
|
@ -71,7 +71,7 @@ void CP25Data::encodeHeader(unsigned char* data)
|
|||
CP25Utils::encode(DUMMY_HEADER, data, 114U, 780U);
|
||||
}
|
||||
|
||||
bool CP25Data::decodeLDU1(const unsigned char* data, bool m_network, bool m_uidOverride)
|
||||
bool CP25Data::decodeLDU1(const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
|
@ -105,12 +105,7 @@ bool CP25Data::decodeLDU1(const unsigned char* data, bool m_network, bool m_uidO
|
|||
return false;
|
||||
}
|
||||
|
||||
// Simple validation of the source id - does not check if no network
|
||||
unsigned int srcId = (rs[6U] << 16) + (rs[7U] << 8) + rs[8U];
|
||||
if (m_network || (!m_network && !m_uidOverride)) {
|
||||
if (srcId < 1000000U)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (rs[0U]) {
|
||||
case P25_LCF_GROUP:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,7 +28,7 @@ public:
|
|||
|
||||
void encodeHeader(unsigned char* data);
|
||||
|
||||
bool decodeLDU1(const unsigned char* data, bool m_network, bool m_uidOverride);
|
||||
bool decodeLDU1(const unsigned char* data);
|
||||
void encodeLDU1(unsigned char* data);
|
||||
|
||||
void encodeLDU2(unsigned char* data);
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
#include <cstring>
|
||||
|
||||
const unsigned char REC62[] = {
|
||||
0x62U, 0x02U, 0x02U, 0x0CU, 0x0BU, 0x1BU, 0x5AU, 0x1AU, 0x2BU, 0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x62U, 0x02U, 0x02U, 0x0CU, 0x0BU, 0x12U, 0x64U, 0x00U, 0x00U, 0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
|
||||
const unsigned char REC63[] = {
|
||||
0x63U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x7AU};
|
||||
0x63U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC64[] = {
|
||||
0x64U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
@ -43,23 +43,23 @@ const unsigned char REC66[] = {
|
|||
0x66U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC67[] = {
|
||||
0x67U, 0xC4U, 0x52U, 0x9BU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x67U, 0xF0U, 0x9DU, 0x6AU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC68[] = {
|
||||
0x68U, 0x9AU, 0xECU, 0xBAU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x68U, 0x19U, 0xD4U, 0x26U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC69[] = {
|
||||
0x69U, 0xB9U, 0xD8U, 0x16U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x69U, 0xE0U, 0xEBU, 0x7BU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC6A[] = {
|
||||
0x6AU, 0x00U, 0x00U, 0x06U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x6AU, 0x00U, 0x00U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
|
||||
const unsigned char REC6B[] = {
|
||||
0x6BU, 0x02U, 0x02U, 0x0CU, 0x0BU, 0x1BU, 0x5AU, 0x1AU, 0x2BU, 0xACU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x6BU, 0x02U, 0x02U, 0x0CU, 0x0BU, 0x12U, 0x64U, 0x00U, 0x00U, 0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
|
||||
const unsigned char REC6C[] = {
|
||||
0x6CU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0xD6U};
|
||||
0x6CU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC6D[] = {
|
||||
0x6DU, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
@ -80,7 +80,7 @@ const unsigned char REC72[] = {
|
|||
0x72U, 0x9BU, 0xDCU, 0x75U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
|
||||
const unsigned char REC73[] = {
|
||||
0x73U, 0x00U, 0x00U, 0x06U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x02U};
|
||||
0x73U, 0x00U, 0x00U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
|
||||
const unsigned char REC80[] = {
|
||||
0x80U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
These are the source files for building the MMDVMHost, the program that interfaces to the MMDVM or DVMega on the one side, and a suitable network on the other. It supports D-Star, DMR, P25 Phase 1, and System Fusion.
|
||||
|
||||
On the D-Star side the MMDVMHost interfaces with the ircDDB Gateway, on DMR it can connect to BrandMeister, DMR+, or HB Link, on System Fusion it connects to the YSF Gateway. On P25 it connects to the P25 Gateway.
|
||||
On the D-Star side the MMDVMHost interfaces with the ircDDB Gateway, on DMR it can connect to BrandMeister, DMR+, HB Link, XLX or [DMRGateway](https://github.com/g4klx/DMRGateway) (to connect to multiple DMR networks at once) on System Fusion it connects to the YSF Gateway. On P25 it connects to the P25 Gateway.
|
||||
|
||||
It builds on 32-bit and 64-bit Linux as well as on Windows using VS2015 on x86 and x64. It can optionally control various Displays. Currently these are:
|
||||
It builds on 32-bit and 64-bit Linux as well as on Windows using Visual Studio 2017 on x86 and x64. It can optionally control various Displays. Currently these are:
|
||||
|
||||
- HD44780 (sizes 2x16, 2x40, 4x16, 4x20)
|
||||
- Support for HD44780 via 4 bit GPIO connection (user selectable pins)
|
||||
|
@ -11,6 +11,7 @@ It builds on 32-bit and 64-bit Linux as well as on Windows using VS2015 on x86 a
|
|||
- Nextion TFTs (sizes 2.4", 2.8", 3.2" and 3.5")
|
||||
- TFT display sold by Hobbytronics in UK
|
||||
- OLED 128x64 (SSD1306)
|
||||
- LCDproc
|
||||
|
||||
The Nextion displays can connect to the UART on the Raspberry Pi, or via a USB to TTL serial converter like the FT-232RL. It may also be connected to the UART output of the MMDVM modem (Arduino Due, STM32, Teensy), or to the UART output on the UMP.
|
||||
|
||||
|
@ -20,4 +21,6 @@ The Hobbytronics TFT Display, which is a Pi-Hat, connects to the UART on the Ras
|
|||
|
||||
The OLED display needs a extra library see OLED.md
|
||||
|
||||
The LCDproc support enables the use of a multitude of other LCD screens. See the [supported devices](http://lcdproc.omnipotent.net/hardware.php3) page on the LCDproc website for more info.
|
||||
|
||||
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.
|
||||
|
|
23
RSSI/RSSI_GM1200E_DEIv1.2.dat
Normal file
23
RSSI/RSSI_GM1200E_DEIv1.2.dat
Normal file
|
@ -0,0 +1,23 @@
|
|||
# This file maps the raw RSSI values to dBm values to send to the DMR network. A number of data
|
||||
# points should be entered and the software will use those to work out the in-between values.
|
||||
#
|
||||
# The format of the file is:
|
||||
# Raw RSSI Value dBm Value
|
||||
#
|
||||
# provided by Wilm DL4OCH
|
||||
# Data taken with F0DEI MMDVM v1.2 and 47k/27k divider in RSSI input
|
||||
|
||||
2263 -43
|
||||
2235 -53
|
||||
2108 -63
|
||||
1910 -73
|
||||
1809 -83
|
||||
1649 -93 # S9
|
||||
1514 -99 # S8
|
||||
1389 -105 # S7
|
||||
1287 -111 # S6
|
||||
1153 -117 # S5
|
||||
1041 -123 # S4
|
||||
977 -129 # S3
|
||||
940 -135 # S2
|
||||
934 -141 # S1
|
|
@ -237,8 +237,11 @@ CSerialController::~CSerialController()
|
|||
bool CSerialController::open()
|
||||
{
|
||||
assert(m_fd == -1);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); /*open in block mode under OSX*/
|
||||
#else
|
||||
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY, 0);
|
||||
#endif
|
||||
if (m_fd < 0) {
|
||||
LogError("Cannot open device - %s", m_device.c_str());
|
||||
return false;
|
||||
|
@ -257,6 +260,23 @@ bool CSerialController::open()
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
termios.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
|
||||
termios.c_cflag &= ~CSIZE;
|
||||
termios.c_cflag |= CS8; /* 8-bit characters */
|
||||
termios.c_cflag &= ~PARENB; /* no parity bit */
|
||||
termios.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
|
||||
termios.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
|
||||
|
||||
/* setup for non-canonical mode */
|
||||
termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
termios.c_oflag &= ~OPOST;
|
||||
|
||||
/* fetch bytes as they become available */
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 1;
|
||||
#else
|
||||
termios.c_lflag &= ~(ECHO | ECHOE | ICANON | IEXTEN | ISIG);
|
||||
termios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY);
|
||||
termios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS);
|
||||
|
@ -264,6 +284,7 @@ bool CSerialController::open()
|
|||
termios.c_oflag &= ~(OPOST);
|
||||
termios.c_cc[VMIN] = 0;
|
||||
termios.c_cc[VTIME] = 10;
|
||||
#endif
|
||||
|
||||
switch (m_speed) {
|
||||
case SERIAL_1200:
|
||||
|
@ -327,9 +348,27 @@ bool CSerialController::open()
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
setNonblock(false);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
int CSerialController::setNonblock(bool nonblock)
|
||||
{
|
||||
int flag = ::fcntl(m_fd, F_GETFD, 0);
|
||||
|
||||
if (nonblock)
|
||||
flag |= O_NONBLOCK;
|
||||
else
|
||||
flag &= ~O_NONBLOCK;
|
||||
|
||||
return ::fcntl(m_fd, F_SETFL, flag);
|
||||
}
|
||||
#endif
|
||||
|
||||
int CSerialController::read(unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
|
@ -344,13 +383,11 @@ int CSerialController::read(unsigned char* buffer, unsigned int length)
|
|||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(m_fd, &fds);
|
||||
|
||||
int n;
|
||||
if (offset == 0U) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
n = ::select(m_fd + 1, &fds, NULL, NULL, &tv);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
@ -380,6 +417,26 @@ int CSerialController::read(unsigned char* buffer, unsigned int length)
|
|||
return length;
|
||||
}
|
||||
|
||||
bool CSerialController::canWrite(){
|
||||
#if defined(__APPLE__)
|
||||
fd_set wset;
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(m_fd, &wset);
|
||||
|
||||
struct timeval timeo;
|
||||
timeo.tv_sec = 0;
|
||||
timeo.tv_usec = 0;
|
||||
|
||||
int rc = select(m_fd + 1, NULL, &wset, NULL, &timeo);
|
||||
if (rc >0 && FD_ISSET(m_fd, &wset))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
|
@ -389,9 +446,10 @@ int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
|||
return 0;
|
||||
|
||||
unsigned int ptr = 0U;
|
||||
|
||||
while (ptr < length) {
|
||||
ssize_t n = ::write(m_fd, buffer + ptr, length - ptr);
|
||||
ssize_t n = 0U;
|
||||
if (canWrite())
|
||||
n = ::write(m_fd, buffer + ptr, length - ptr);
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
LogError("Error returned from write(), errno=%d", errno);
|
||||
|
|
|
@ -53,6 +53,10 @@ public:
|
|||
|
||||
virtual void close();
|
||||
|
||||
#if defined(__APPLE__)
|
||||
virtual int setNonblock(bool nonblock);
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::string m_device;
|
||||
SERIAL_SPEED m_speed;
|
||||
|
@ -65,6 +69,8 @@ private:
|
|||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int readNonblock(unsigned char* buffer, unsigned int length);
|
||||
#else
|
||||
bool canWrite();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20170501";
|
||||
const char* VERSION = "20170719";
|
||||
|
||||
#endif
|
||||
|
|
899
YSFControl.cpp
899
YSFControl.cpp
File diff suppressed because it is too large
Load diff
21
YSFControl.h
21
YSFControl.h
|
@ -25,6 +25,7 @@
|
|||
#include "YSFPayload.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "StopWatch.h"
|
||||
#include "YSFFICH.h"
|
||||
#include "Display.h"
|
||||
#include "Defines.h"
|
||||
#include "Timer.h"
|
||||
|
@ -34,9 +35,11 @@
|
|||
|
||||
class CYSFControl {
|
||||
public:
|
||||
CYSFControl(const std::string& callsign, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool lowDeviation, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
||||
CYSFControl(const std::string& callsign, bool selfOnly, CYSFNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool lowDeviation, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
||||
~CYSFControl();
|
||||
|
||||
void setSQL(bool on, unsigned char value);
|
||||
|
||||
bool writeModem(unsigned char* data, unsigned int len);
|
||||
|
||||
unsigned int readModem(unsigned char* data);
|
||||
|
@ -45,11 +48,15 @@ public:
|
|||
|
||||
private:
|
||||
unsigned char* m_callsign;
|
||||
unsigned char* m_selfCallsign;
|
||||
bool m_selfOnly;
|
||||
CYSFNetwork* m_network;
|
||||
CDisplay* m_display;
|
||||
bool m_duplex;
|
||||
bool m_lowDeviation;
|
||||
bool m_remoteGateway;
|
||||
bool m_sqlEnabled;
|
||||
unsigned char m_sqlValue;
|
||||
CRingBuffer<unsigned char> m_queue;
|
||||
RPT_RF_STATE m_rfState;
|
||||
RPT_NET_STATE m_netState;
|
||||
|
@ -69,10 +76,7 @@ private:
|
|||
unsigned char* m_rfDest;
|
||||
unsigned char* m_netSource;
|
||||
unsigned char* m_netDest;
|
||||
unsigned char* m_lastFrame;
|
||||
bool m_lastFrameValid;
|
||||
unsigned char m_lastMode;
|
||||
unsigned char m_lastMR;
|
||||
CYSFFICH m_lastFICH;
|
||||
unsigned char m_netN;
|
||||
CYSFPayload m_rfPayload;
|
||||
CYSFPayload m_netPayload;
|
||||
|
@ -84,6 +88,10 @@ private:
|
|||
unsigned int m_rssiCount;
|
||||
FILE* m_fp;
|
||||
|
||||
bool processVWData(bool valid, unsigned char *data);
|
||||
bool processDNData(bool valid, unsigned char *data);
|
||||
bool processFRData(bool valid, unsigned char *data);
|
||||
|
||||
void writeQueueRF(const unsigned char* data);
|
||||
void writeQueueNet(const unsigned char* data);
|
||||
void writeNetwork(const unsigned char* data, unsigned int count);
|
||||
|
@ -96,8 +104,7 @@ private:
|
|||
bool writeFile(const unsigned char* data);
|
||||
void closeFile();
|
||||
|
||||
bool insertSilence(const unsigned char* data, unsigned char n);
|
||||
void insertSilence(unsigned int count);
|
||||
bool checkCallsign(const unsigned char* callsign) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -42,7 +42,8 @@ const unsigned char YSF_DT_DATA_FR_MODE = 0x01U;
|
|||
const unsigned char YSF_DT_VD_MODE2 = 0x02U;
|
||||
const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U;
|
||||
|
||||
const unsigned char YSF_CM_GROUP = 0x00U;
|
||||
const unsigned char YSF_CM_GROUP1 = 0x00U;
|
||||
const unsigned char YSF_CM_GROUP2 = 0x01U;
|
||||
const unsigned char YSF_CM_INDIVIDUAL = 0x03U;
|
||||
|
||||
const unsigned char YSF_MR_NOT_BUSY = 0x01U;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue