411 lines
8.9 KiB
C++
411 lines
8.9 KiB
C++
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "PrtCnvApplication.hpp"
|
|
#include "PrtCnvThreadStarter.hpp"
|
|
#include "PrtCnvThread.hpp"
|
|
#include "PrtCnvCentralThread.hpp"
|
|
#include "PrtCnvTelegramLogThread.hpp"
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
#include <QCoreApplication>
|
|
#include <QThread>
|
|
|
|
namespace PrtCnv
|
|
{
|
|
|
|
static std::string threadIdToString(PrtCnvApplication::E_ThreadId id)
|
|
{
|
|
switch (id)
|
|
{
|
|
case PrtCnvApplication::e_Central:
|
|
return "Central";
|
|
case PrtCnvApplication::e_Radio:
|
|
return "Radio";
|
|
case PrtCnvApplication::e_Db:
|
|
return "Db";
|
|
case PrtCnvApplication::e_Log:
|
|
return "Log";
|
|
case PrtCnvApplication::e_Injection:
|
|
return "Injection";
|
|
case PrtCnvApplication::e_RadioTraffic:
|
|
return "RadioTraffic";
|
|
case PrtCnvApplication::e_ThreadIdMax:
|
|
break;
|
|
}
|
|
return std::to_string(id);
|
|
}
|
|
|
|
PrtCnvApplication::PrtCnvApplication()
|
|
: m_Config(nullptr)
|
|
, m_exerciseId(0)
|
|
, m_accessMutex(QMutex::Recursive)
|
|
, m_logger(getLogger("PrtCnvApplication"))
|
|
{}
|
|
|
|
|
|
PrtCnvApplication::~PrtCnvApplication()
|
|
{
|
|
delete m_Config;
|
|
for (const auto &ti : m_threadInfo)
|
|
delete ti.thread;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PrtCnvApplication::waitForCreate(const E_ThreadId a_threadId)
|
|
{
|
|
INFO_LOG(m_logger) << "Wait for others until we can create " << threadIdToString(a_threadId);
|
|
setConstructed(a_threadId);
|
|
switch (a_threadId)
|
|
{
|
|
case e_Central:
|
|
while (!(isConstructed(e_Db) &&
|
|
isConstructed(e_Radio) &&
|
|
isConstructed(e_Log) &&
|
|
isConstructed(e_Injection)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_Radio:
|
|
while (!(isConstructed(e_Db) &&
|
|
isConstructed(e_Central) &&
|
|
isConstructed(e_Log) &&
|
|
isConstructed(e_Injection)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_Db:
|
|
while (!(isConstructed(e_Radio) &&
|
|
isConstructed(e_Central)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
INFO_LOG(m_logger) << "Now we can create " << threadIdToString(a_threadId);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PrtCnvApplication::waitForInit(E_ThreadId a_threadId)
|
|
{
|
|
INFO_LOG(m_logger) << "Wait for others until we can initialize " << threadIdToString(a_threadId);
|
|
setCreated(a_threadId);
|
|
switch (a_threadId)
|
|
{
|
|
case e_Central:
|
|
while (!(isCreated(e_Db) &&
|
|
isCreated(e_Radio)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_Radio:
|
|
while (!(isCreated(e_Db) &&
|
|
isCreated(e_Central)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_Db:
|
|
while (!(isCreated(e_Radio) &&
|
|
isCreated(e_Central)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
INFO_LOG(m_logger) << "Now we can initialize " << threadIdToString(a_threadId);
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrtCnvApplication::waitForStart(E_ThreadId a_threadId)
|
|
{
|
|
INFO_LOG(m_logger) << "Wait for others until we can start " << threadIdToString(a_threadId);
|
|
setInitialized(a_threadId);
|
|
switch (a_threadId)
|
|
{
|
|
case e_Central:
|
|
while (!(isStarted(e_Db) &&
|
|
isInitialized(e_Radio) &&
|
|
isStarted(e_Log) &&
|
|
isStarted(e_Injection)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_Radio:
|
|
while (!(isStarted(e_Db) &&
|
|
isInitialized(e_Central) &&
|
|
isStarted(e_Log) &&
|
|
isStarted(e_Injection) &&
|
|
isInitialized(e_RadioTraffic)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_Db:
|
|
while (!(isInitialized(e_Radio) &&
|
|
isInitialized(e_Central) &&
|
|
isStarted(e_Log)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
|
|
case e_RadioTraffic:
|
|
while (!(isInitialized(e_Radio) &&
|
|
isStarted(e_Log)))
|
|
{
|
|
DEBUG_LOG(m_logger) << "wait...";
|
|
QThread::sleep(1);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
INFO_LOG(m_logger) << "Now we can start " << threadIdToString(a_threadId);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PrtCnvApplication::waitForExec(E_ThreadId a_threadId)
|
|
{
|
|
setStarted(a_threadId);
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrtCnvApplication::startApp()
|
|
{
|
|
createApplication();
|
|
init();
|
|
start();
|
|
}
|
|
|
|
void PrtCnvApplication::shutdownApp()
|
|
{
|
|
stop();
|
|
deinit();
|
|
destroy();
|
|
for (const auto &ti : m_threadInfo)
|
|
ti.thread->quit();
|
|
for (const auto &ti : m_threadInfo)
|
|
ti.thread->wait();
|
|
for (auto &ti : m_threadInfo)
|
|
{
|
|
delete ti.thread;
|
|
ti.thread = nullptr;
|
|
}
|
|
}
|
|
|
|
void PrtCnvApplication::setCleanDb(bool bCleanDb)
|
|
{
|
|
PrtCnvThread::m_DoCleanDb = bCleanDb;
|
|
}
|
|
|
|
void PrtCnvApplication::setExerciseId(int exerciseId)
|
|
{
|
|
m_exerciseId = exerciseId;
|
|
}
|
|
|
|
void PrtCnvApplication::setConfigFile(const QString &configFile)
|
|
{
|
|
m_ConfigFileName = configFile;
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t PrtCnvApplication::createApplication()
|
|
{
|
|
setName(QStringLiteral("Common"));
|
|
if (m_ConfigFileName.isEmpty())
|
|
{
|
|
m_ConfigFileName = QCoreApplication::applicationDirPath();
|
|
if (m_exerciseId > 0)
|
|
m_ConfigFileName += QStringLiteral("/PrtCnv_ex_") + QString::number(m_exerciseId) + QStringLiteral(".dat");
|
|
else
|
|
m_ConfigFileName += QStringLiteral("/PrtCnv.dat");
|
|
}
|
|
m_Config = new NGL::Settings(m_ConfigFileName);
|
|
std::cout << "Use config-file: " << qPrintable(m_ConfigFileName) << std::endl;
|
|
|
|
for (int i = 0; i < e_ThreadIdMax; i++)
|
|
m_threadInfo[i].thread = new PrtCnvThreadStarter((E_ThreadId)i, m_ConfigFileName, this);
|
|
|
|
N_AppComponent::AppComponent::create(m_Config);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t PrtCnvApplication::start()
|
|
{
|
|
|
|
for (const auto &ti : m_threadInfo)
|
|
ti.thread->start();
|
|
|
|
N_AppComponent::AppComponent::start();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PrtCnv::PrtCnvThreadStarter *PrtCnvApplication::getThreadStarter(const E_ThreadId a_threadId)
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return nullptr;
|
|
|
|
QMutexLocker l(&m_accessMutex);
|
|
return m_threadInfo[a_threadId].thread;
|
|
}
|
|
|
|
void PrtCnvApplication::setDatabaseConnectionParams(const QString &driver,
|
|
const QString &hostName,
|
|
const QString &database,
|
|
const QString &schemaName,
|
|
const QString &userName,
|
|
const QString &password)
|
|
{
|
|
m_dbDriver = driver;
|
|
m_dbHostName = hostName;
|
|
m_dbDatabaseName = database;
|
|
m_dbSchemaName = schemaName;
|
|
m_dbUserName = userName;
|
|
m_dbPassword = password;
|
|
}
|
|
|
|
void PrtCnvApplication::logWlsTelegram(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *tele,
|
|
bool bIsSend)
|
|
{
|
|
const auto threadHandler = m_threadInfo[e_Log].thread;
|
|
PrtCnvTelegramLogThread *t = static_cast<PrtCnvTelegramLogThread*>(threadHandler ? threadHandler->getThread() : nullptr);
|
|
if (t)
|
|
t->writeWlsTelegramLog(tele, bIsSend, 0);
|
|
}
|
|
|
|
|
|
bool PrtCnvApplication::isConstructed(const E_ThreadId a_threadId) const
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return false;
|
|
QMutexLocker l(&m_accessMutex);
|
|
return m_threadInfo[a_threadId].isConstructed;
|
|
}
|
|
|
|
|
|
void PrtCnvApplication::setConstructed(const E_ThreadId a_threadId)
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return;
|
|
QMutexLocker l(&m_accessMutex);
|
|
m_threadInfo[a_threadId].isConstructed = true;
|
|
}
|
|
|
|
|
|
bool PrtCnvApplication::isInitialized(const E_ThreadId a_threadId) const
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return false;
|
|
QMutexLocker l(&m_accessMutex);
|
|
return m_threadInfo[a_threadId].isInitialized;
|
|
}
|
|
|
|
|
|
void PrtCnvApplication::setInitialized(const E_ThreadId a_threadId)
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return;
|
|
QMutexLocker l(&m_accessMutex);
|
|
m_threadInfo[a_threadId].isInitialized = true;
|
|
}
|
|
|
|
|
|
bool PrtCnvApplication::isCreated(const E_ThreadId a_threadId) const
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return false;
|
|
QMutexLocker l(&m_accessMutex);
|
|
return m_threadInfo[a_threadId].isCreated;
|
|
}
|
|
|
|
|
|
void PrtCnvApplication::setCreated(const E_ThreadId a_threadId)
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return;
|
|
QMutexLocker l(&m_accessMutex);
|
|
m_threadInfo[a_threadId].isCreated = true;
|
|
}
|
|
|
|
|
|
bool PrtCnvApplication::isStarted(const E_ThreadId a_threadId) const
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return false;
|
|
QMutexLocker l(&m_accessMutex);
|
|
return m_threadInfo[a_threadId].isStarted;
|
|
}
|
|
|
|
|
|
void PrtCnvApplication::setStarted(const E_ThreadId a_threadId)
|
|
{
|
|
if (a_threadId < e_Central || a_threadId >= e_ThreadIdMax)
|
|
return;
|
|
QMutexLocker l(&m_accessMutex);
|
|
m_threadInfo[a_threadId].isStarted = true;
|
|
}
|
|
|
|
}
|