Files
qt6-migration-pipeline/TetraIF/PrtCnv/PrtCnvRadioThread.hpp
T
2026-07-14 12:07:36 +02:00

420 lines
8.8 KiB
C++

#pragma once
#include "PrtCnvSocketThread.hpp"
#include "PrtCnvBroadcastMgr.hpp"
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
#include <set>
#include <QList>
#include <QMutex>
#include <TrainingAreaBase/training_area_telegrams.h>
#define MAX_IDENTITY 65535
namespace PrtCnv
{
struct BiteError
{
int errorNumber = 0;
int canDeviceNumber = 0;
int subdeviceNumber = 0;
int uniqueId = 0;
};
class PrtCnvCentralThread;
class PrtCnvMember;
class PrtCnvRadioTrafficThread;
class PrtCnvStoredRadioTelegram;
class PrtCnvRadioThread : public PrtCnv::PrtCnvSocketThread
{
Q_OBJECT
public:
PrtCnvRadioThread(int exerciseId, PrtCnvThreadStarter* a_parent);
int32_t create(NGL::Settings *settings) override;
int32_t destroy() override;
int32_t init() override;
int32_t start() override;
void prepareCleanUp();
void sendEnvironmentTelegramTimerNow();
void exerciseEquipmentChanged(const TrainingAreaBase::TetraIcd::ExerciseEquipmentAssignmentComplete &data);
protected:
void onCheckMemberForValidLogin(int identity, int issi);
void sendLoginAccept(int identity, int issi, int exerciseId, bool bWithMastering);
bool isIdentityInCurrentExercise(int identity) const;
int exerciseIdForIdentity(int identity) const;
void removeMasteringMember(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_loginTelegram, PrtCnvMember *member,
PrtCnvMember *issiMember,
int masterIdentity,
int masterIssi);
protected:
PrtCnvCentralThread *m_CentralThread;
PrtCnvRadioTrafficThread *m_radioTrafficThread;
public:
Q_SIGNALS:
void checkSendToCentral();
void checkSendToRadio();
void cleant();
void stopped();
void checkMemberForValidLogin(int identity, int issi);
void tetraConnectionState(bool connected);
void areaEffectSimulationActivated(int wirkfeldKennung);
void areaEffectSimulationDeactivated(int wirkfeldKennung);
void initDone();
void playerLicencedChanged(int equipNo, N_CoPrtCnv::E_LicensingKind kind);
void warehouseMessageFromPtrCnv(const QByteArray &jsonData);
protected:
uint32_t m_SendCounter;
uint32_t m_HostISSI;
const uint32_t START_COUNTER;
const uint32_t END_COUNTER;
QTimer *m_EnvironmentTelegramTimer;
uint32_t m_BroadcastISSI;
QString m_LoginPathWithPrefix;
int m_ExerciseId;
std::set<uint16_t> m_AllowedIdentities;
bool m_DoLicenseDespiteSelftestOrConfigFailure;
bool m_DoCheckIdentity;
PrtCnvBroadcastMgr m_BroadcastManager;
bool m_DoDumpReceivedTelegrams;
bool m_DoDumpSentTelegrams;
bool m_DoUseSDSTL;
std::set<uint16_t> m_DoNeedActPosResp;
uint32_t m_EmergencyCallISSI;
void sendTelegram(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_telegram,
PrtCnvStoredRadioTelegram *a_handle,
const bool a_doCheckWhetherExpired = true);
void doRegister();
void registerGroups();
void handleRegisterRsp(const uint8_t a_regsitrationStatus);
public:
enum class E_TrafficLoad
{
Unknown = -1,
NormalLoad = 0,
HighLoad,
FullLoad
};
protected:
N_CoPrtCnv::CoPrtCnvRadioTelegram *m_EnvironmentTelegram;
E_TrafficLoad m_SendLoad;
uint32_t m_SendQueueFullLoad;
uint32_t m_SendQueueHighLoad;
uint32_t m_SendTelegramsNormalLoad;
uint32_t m_SendTelegramsHighLoad;
uint32_t m_SendTelegramsFullLoad;
uint32_t m_SentTelegrams;
uint32_t m_SentBytes;
uint32_t m_TickCounter;
uint32_t m_TicksPerSecond;
static const int AVERAGE_COUNT = 10;
uint32_t m_SentBytesAverage[AVERAGE_COUNT];
uint8_t m_AverageIndex;
uint32_t m_ReceivedTelegrams;
uint32_t m_ReceivedBytes;
uint32_t m_ReceivedBytesAverage[AVERAGE_COUNT];
std::set<uint32_t> m_ListenGroups;
bool m_bUseScrambling;
NGL::INGLLogger &m_loggerStats;
std::unordered_map<int, std::unordered_set<int>> m_exerciseEquipmentAssignments;
std::unordered_map<int, TrainingAreaBase::TetraIcd::GroupIssiInformation> m_groupIssiInformation;
mutable QMutex m_exerciseEquipmentAssignmentMutex;
private:
bool sendAnswer(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_radioTelegram);
void handleReceivedTelegram(const QByteArray &data);
void handleDataIndReq(const QByteArray &data, bool bIsMaybeScrambled);
void handleLoginTelegram(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_loginTelegram);
void handleFragmentedTelegram(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_fragmentedTelegram);
void sendFehlermeldungGefechtsfeldToCentral(const uint16_t a_identity,
const TrainingAreaBase::TetraIcd::CtaDataError::Reason a_errorCause,
const gef_telegramm_id_et a_telegramId = GEF_BESTAETIGUNG);
uint32_t getDestinationISSI(const uint16_t a_TNE_Id) const;
bool handleBITEEXT_Telegram(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_BITE_RadioTelegram);
bool handleBITE_Telegram(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_BITE_RadioTelegram,
TrainingAreaBase::TetraIcd::BiteReport::LoginType anmeldeart,
uint32_t ergebnisCAN,
uint32_t ergebnisAusstattung,
uint32_t aktuelleKonfiguration,
uint32_t konfigurationsvergleich,
const QList<PrtCnv::BiteError> &fehlerListe
);
void sendLoginResponse(const N_CoPrtCnv::CoPrtCnvRadioTelegram::E_LoginStatus a_loginTelegramStatus, const uint16_t a_identity, const uint32_t a_ISSI);
void sendLoginResponse(const N_CoPrtCnv::CoPrtCnvRadioTelegram::E_LoginStatus a_loginTelegramStatus,
const uint16_t a_identity, const uint32_t a_ISSI, const TrainingAreaBase::TetraIcd::GroupIssiInformation &group);
void sendLizenzierungTneToRadio(const uint16_t a_identity, const uint32_t a_issi,
const N_CoPrtCnv::E_LicensingKind a_licensingKind,
const N_CoPrtCnv::E_LicensingErrorCode a_errorCause);
void writeLoginLog(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_radioTelegram, const QString &a_prosaText);
void writeLoginLog(const N_CoPrtCnv::CoPrtCnvRadioTelegram *a_radioTelegram, const QString &a_prosaText);
void writeLoginLog(uint32_t identity, uint32_t issi, const QString &a_prosaText);
void initIdentityArray();
uint16_t readIdentity(const QByteArray& a_idAsText, const uint32_t a_line, const QString& a_fileName);
bool isIdentityValid(uint16_t a_identity) const;
void setIdentityVaild(uint16_t a_identity);
void sendFragmentedTelegram(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_telegram);
uint16_t sendToSocket(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_telegram);
void handleReportIndReq(const QByteArray &data);
void prepareWareHouseMessage(qint32 equipNr,
bool doLicence,
qint64 ergebnisCAN,
qint64 ergebnisAusstattung,
qint64 aktuelleKonfiguration,
qint64 konfigurationsvergleich,
const QList<PrtCnv::BiteError> &fehlerListe);
protected Q_SLOTS:
void onSendEnvironmentTelegramTimerNow();
void timeoutAliveAndConnection() override;
void timeoutTick() override;
void checkSend();
void readyRead() override;
void disconnected() override;
void connected() override;
void timeoutEnvironmentTelegram();
void doClean();
void doStart();
void doStop();
void onBroadcastTelegramsRequestFromCentral(int equipmentNumber, int broadcastIndex, int resetCounter);
private:
void handleStatusIndReq(const QByteArray &data);
void handleAirInterfaceLoadReq(const QByteArray &data);
void computeAndLogTrafficStatistics();
bool isSendLimitReached() const;
void sendScrambledContent(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_telegram) const;
bool unscrambleContent(N_CoPrtCnv::CoPrtCnvRadioTelegram &a_telegram) const;
friend class PrtCnvCentralThread;
};
std::ostream &operator<<(std::ostream &os, const PrtCnvRadioThread::E_TrafficLoad tl);
}