Files
qt5-legatus-legacy/TetraIF/PrtCnv/PrtCnvTelegramLogThread.cpp
2026-08-13 18:33:10 +02:00

183 lines
6.2 KiB
C++

// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
// manual class headers
#include "PrtCnvTelegramLogThread.hpp"
#include <CoPrtCnv/CoPrtCnvCentralTelegram.hpp>
#include <CoPrtCnv/CoPrtCnvLogHeader.hpp>
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QDateTime>
#include <nglsettings/nglsettings_settings.h>
#include <QtCore/QCoreApplication>
#include <TrainingAreaBase/training_area_telegrams.h>
#ifdef Q_OS_WIN
#include <windows.h>
static int gettimeofday(struct timeval *__p, void *__t)
{
union {
unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} now;
constexpr long long SECONDS_SINCE_1601 = 11644473600LL;
constexpr long long USEC_IN_SEC = 1000000LL;
GetSystemTimeAsFileTime(&now.ft);
__p->tv_usec = (long)((now.ns100 / 10LL) % USEC_IN_SEC);
__p->tv_sec = (long)(((now.ns100 / 10LL) / USEC_IN_SEC) - SECONDS_SINCE_1601);
return (0);
}
#else
#include <sys/time.h>
#endif
namespace PrtCnv
{
// ---------------------------------------------------------------
PrtCnvTelegramLogThread::PrtCnvTelegramLogThread(PrtCnvThreadStarter* a_parent)
: PrtCnvThread(a_parent, "PrtCnvTelegramLogThread")
, m_DoLogCentralTelegram(true)
, m_DoLogWlsTelegram(true)
, m_DoLogRadioTelegram(true)
{
m_Name = QStringLiteral("TelegramLog");
}
// ---------------------------------------------------------------
int32_t PrtCnvTelegramLogThread::create(NGL::Settings *settings)
{
PrtCnvThread::create(settings);
connect(this, &PrtCnvTelegramLogThread::telegramLogReceived,
this, &PrtCnvTelegramLogThread::writeTelegramLog,
Qt::QueuedConnection);
return 0;
}
// ---------------------------------------------------------------
int32_t PrtCnvTelegramLogThread::init()
{
PrtCnvThread::init();
m_DoLogCentralTelegram = m_Config->getBoolean(QStringLiteral("Common"), QStringLiteral("LogCentralTelegrams"), true);
m_DoLogWlsTelegram = m_Config->getBoolean(QStringLiteral("Common"), QStringLiteral("LogWlsTelegrams"), true);
m_DoLogRadioTelegram = m_Config->getBoolean(QStringLiteral("Common"), QStringLiteral("LogRadioTelegrams"), true);
QString path = m_Config->getString(QStringLiteral("Common"), QStringLiteral("LogTelegramPath"), QStringLiteral("."));
if (!QDir::isAbsolutePath(path))
path = QCoreApplication::applicationDirPath() + QStringLiteral("/../") + path;
m_LogTelegramPathWithPrefix = path + QLatin1Char('/') + m_Config->getString(QStringLiteral("Common"), QStringLiteral("LogTelegramPrefix"), QStringLiteral("PrtCnv_"));
if (!m_LogTelegramPathWithPrefix.endsWith(QLatin1Char('_')))
m_LogTelegramPathWithPrefix += QLatin1Char('_');
// create the telegram-log-path when it not yet exists
QFileInfo fileInfo(m_LogTelegramPathWithPrefix);
QDir dir;
dir.mkpath(fileInfo.absolutePath());
INFO_LOG(m_logger);
return 0;
}
static inline int setSend(int protocol, bool bIsSend)
{
return (protocol | (bIsSend ? N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend : N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive));
}
// ---------------------------------------------------------------
// Writes a received or sent central-telegram into log-file
// ---------------------------------------------------------------
void PrtCnvTelegramLogThread::writeCentralTelegramLog(N_CoPrtCnv::CoPrtCnvCentralTelegram *a_centralTelegram, bool a_isSend, int a_priority)
{
if (!m_DoLogCentralTelegram)
return;
emit telegramLogReceived(a_centralTelegram->data(),
setSend(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral, a_isSend),
a_priority);
}
// ---------------------------------------------------------------
// Writes a received or sent wls-telegram into log-file
// ---------------------------------------------------------------
void PrtCnvTelegramLogThread::writeWlsTelegramLog(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *tele, bool a_isSend, int a_priority)
{
if (!m_DoLogWlsTelegram)
return;
N_CoPrtCnv::CoPrtCnvCentralTelegram central(*tele);
emit telegramLogReceived(central.data(),
setSend(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolWls, a_isSend),
a_priority);
}
// ---------------------------------------------------------------
// Writes a received or sent radio-telegram into log-file
// ---------------------------------------------------------------
void PrtCnvTelegramLogThread::writeRadioTelegramLog(const QByteArray &tele, bool a_isSend, int a_priority)
{
if (!m_DoLogRadioTelegram)
return;
emit telegramLogReceived(tele,
setSend(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolTetra, a_isSend),
a_priority);
}
// ---------------------------------------------------------------
// Writes the telegram to the file
// ---------------------------------------------------------------
void PrtCnvTelegramLogThread::writeTelegramLog(const QByteArray &a_data, int a_protocolType, int a_priority)
{
// get time with microseconds
timeval tv;
gettimeofday(&tv, nullptr);
uint64_t exactTime = tv.tv_sec;
exactTime = exactTime << 32;
exactTime += tv.tv_usec;
// generate the filename of the telegram-file: "PrefixYYMMDD_HH.krlog"
QString fileName = QStringLiteral("%1%2.krlog")
.arg(m_LogTelegramPathWithPrefix, QDateTime::fromSecsSinceEpoch(tv.tv_sec).toString(QStringLiteral("yyMMdd_hh")));
// open the log-file
QFile telegramFile(fileName);
telegramFile.open(QIODevice::WriteOnly | QIODevice::Append);
// write header
N_CoPrtCnv::CoPrtCnvLogHeader lh;
lh.m_Length = a_data.size() + sizeof(N_CoPrtCnv::CoPrtCnvLogHeader);
lh.m_Version = 3;
lh.m_Priority = a_priority;
lh.m_Protocol = a_protocolType;
lh.m_Time = exactTime;
lh.m_Reserved = 0;
telegramFile.write(reinterpret_cast<const char*>(&lh), sizeof(N_CoPrtCnv::CoPrtCnvLogHeader));
// write telegram-data
telegramFile.write(a_data);
telegramFile.close();
}
} // namespace PrtCnv