Files
qt6-migration-pipeline/TetraIF/CoPrtCnv/CoPrtCnvRadioTelegram.cpp
T
2026-07-14 12:07:36 +02:00

1794 lines
41 KiB
C++

#include "CoPrtCnvRadioTelegram.hpp"
#include <time.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
using N_CoPrtCnv::CoPrtCnvRadioTelegram;
using namespace N_CoPrtCnv;
constexpr uint8_t CoPrtCnvRadioTelegram::MAGIC_NUMBER;
constexpr uint16_t CoPrtCnvRadioTelegram::DATA_IND_REQ_WITH_TL_HEADER_LENGTH;
constexpr uint16_t CoPrtCnvRadioTelegram::DATA_IND_REQ_HEADER_LENGTH;
constexpr uint16_t CoPrtCnvRadioTelegram::DATA_IND_REQ_NO_TL_HEADER_LENGTH;
constexpr uint16_t CoPrtCnvRadioTelegram::MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH;
constexpr uint16_t CoPrtCnvRadioTelegram::PAYLOAD_STATUS_LENGTH;
constexpr uint8_t CoPrtCnvRadioTelegram::MAX_NBR_OF_FRAGMENTS;
int CoPrtCnvRadioTelegram::s_2ndDelay = 60;
int CoPrtCnvRadioTelegram::s_3rdDelay = 60;
int CoPrtCnvRadioTelegram::s_maxBroadcastSendCnt = 0;
bool CoPrtCnvRadioTelegram::s_etsMode = false;
static const N_CoPrtCnv::CoPrtCnvRadioTelegram::E_ProtocolIdentifier
s_protocolIdentifier = N_CoPrtCnv::CoPrtCnvRadioTelegram::e_TDSMessageWithoutSDS_TL;
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI)
: m_data(9, Qt::Uninitialized),
m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
setHeader(m_data, e_RegisterInd);
setSrcISSI(a_sourceISSI);
}
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI,
const std::set<uint32_t> &groups)
: m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
uint16_t len = groups.size();
if (len > 5)
len = 5;
m_data.resize(12 + len * 4);
setHeader(m_data, e_GroupMonitorReq);
setSrcISSI(a_sourceISSI);
uint8_t mode = 1;
set1Byte(m_data, 9, mode);
set2Byte(m_data, 10, len);
std::set<uint32_t>::iterator it = groups.begin();
for (uint16_t i = 0; i < len; i++)
{
set4Byte(m_data, 12 + i * 4, *it);
++it;
}
}
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI,
const E_DeliveryStatusForTL_Report a_delivery)
: m_data(17, Qt::Uninitialized),
m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
setHeader(m_data, e_ReportIndReq);
setSrcISSI(a_sourceISSI);
setDestISSI(a_sourceISSI);
set1Byte(m_data, 13, s_protocolIdentifier);
set1Byte(m_data, 14, 0);
set1Byte(m_data, 15, 0);
set1Byte(m_data, 16, a_delivery);
}
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const QByteArray &a_data)
: m_data(a_data),
m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
}
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const gef_telegramm_id_et a_telegramId, const uint16_t a_payloadSize, const uint16_t a_identity)
: m_data(a_payloadSize + DATA_IND_REQ_HEADER_LENGTH, '\0'),
m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
setHeader(m_data, e_DataIndReq);
fillDataIndReqHeader(m_data);
m_PayloadIndex = DATA_IND_REQ_HEADER_LENGTH - PAYLOAD_STATUS_LENGTH;
set1Byte(m_data, m_PayloadIndex++, e_NotFragmented);
set1Byte(m_data, m_PayloadIndex++, a_telegramId);
set1Byte(m_data, m_PayloadIndex++, 0);
set1Byte(m_data, m_PayloadIndex--, 0);
setIdentity(a_identity);
m_PayloadIndex += 2;
}
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const E_LoginStatus a_loginTelegramStatus, const uint16_t a_identity, uint32_t a_issi)
: m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
const bool withGroupIssis = (a_loginTelegramStatus & e_LoginOtherExercise) == e_LoginOtherExercise;
m_data.resize(DATA_IND_REQ_HEADER_LENGTH + (withGroupIssis ? 12 : 3));
setHeader(m_data, e_DataIndReq);
fillDataIndReqHeader(m_data);
setDestISSI(a_issi);
uint16_t size = m_data.size();
set2Byte(m_data, DATA_IND_REQ_WITH_TL_HEADER_LENGTH, 8 * (size - DATA_IND_REQ_HEADER_LENGTH_WITHOUT_PAYLOAD_HEADER));
m_PayloadIndex = DATA_IND_REQ_HEADER_LENGTH - PAYLOAD_STATUS_LENGTH;
set1Byte(m_data, m_PayloadIndex++, e_NotFragmented + e_LoginTelegram);
set1Byte(m_data, m_PayloadIndex++, (a_identity >> 8) & 0x00FF);
set1Byte(m_data, m_PayloadIndex++, a_identity & 0x00FF);
set1Byte(m_data, m_PayloadIndex++, a_loginTelegramStatus);
}
void CoPrtCnvRadioTelegram::setLoginIssis(int hostIssi, int groupIssi1, int groupIssi2)
{
setPayload3Byte(hostIssi);
setPayload3Byte(groupIssi1);
setPayload3Byte(groupIssi2);
}
CoPrtCnvRadioTelegram::CoPrtCnvRadioTelegram(const std::shared_ptr<CoPrtCnvRadioTelegram> &a_bigTelegram,
const uint8_t a_fragmentIndex,
bool &a_error)
: m_data(),
m_PayloadIndex(0),
m_BroadcastCounter(0),
m_NextSendTime(0),
m_IsBroadcastOnly(false),
m_BroadcastOnlyTelegram(nullptr),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram"))
{
static const uint16_t MAX_TELEGRAM_SIZE = MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH - PAYLOAD_STATUS_LENGTH;
const int payloadSize = a_bigTelegram->getSize() - DATA_IND_REQ_HEADER_LENGTH;
const uint8_t nbrOfFragmentedTelegrams = uint8_t((payloadSize - 1) / MAX_TELEGRAM_SIZE);
if (nbrOfFragmentedTelegrams > (MAX_NBR_OF_FRAGMENTS - 1))
{
ERROR_LOG(m_logger) << "Radio-telegram is too big (" << nbrOfFragmentedTelegrams + 1
<< " fragments). There are max " << MAX_NBR_OF_FRAGMENTS
<< " fragments of size=" << MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH
<< " (=" << MAX_NBR_OF_FRAGMENTS *MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH
<< " bytes) possible.";
a_error = true;
return;
}
if (nbrOfFragmentedTelegrams == 0)
{
ERROR_LOG(m_logger) << "Radio-telegram is too small for fragmentation. It must have at least a size of "
<< (MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH + 1);
a_error = true;
return;
}
uint8_t payloadStatus = e_FirstFragment | nbrOfFragmentedTelegrams;
const uint16_t payloadSizeNormal = uint16_t(payloadSize / (nbrOfFragmentedTelegrams + 1));
const uint16_t payloadSizeLast = uint16_t(payloadSize - (nbrOfFragmentedTelegrams * payloadSizeNormal));
uint16_t size = payloadSizeNormal;
if (0 != a_fragmentIndex)
{
if (nbrOfFragmentedTelegrams != a_fragmentIndex)
{
payloadStatus = e_MiddleFragment | (nbrOfFragmentedTelegrams - a_fragmentIndex);
}
else
{
payloadStatus = e_LastFragment;
size = payloadSizeLast;
}
}
size += PAYLOAD_STATUS_LENGTH;
m_data.resize(size + DATA_IND_REQ_WITH_TL_HEADER_LENGTH + sizeof(PrtCnvRadioGwHeader));
setHeader(m_data, e_DataIndReq);
fillDataIndReqHeader(m_data);
m_PayloadIndex = DATA_IND_REQ_HEADER_LENGTH - PAYLOAD_STATUS_LENGTH;
set1Byte(m_data, m_PayloadIndex++, payloadStatus);
if (size > 1)
{
const char *srcData = a_bigTelegram->getData() + DATA_IND_REQ_HEADER_LENGTH + a_fragmentIndex * payloadSizeNormal;
const uint8_t *ptr = reinterpret_cast<const uint8_t *>(srcData);
setPayloadData(ptr, size - 1);
}
else
{
ERROR_LOG(m_logger) << "Internal error: size must be bigger than 1";
a_error = true;
return;
}
a_error = false;
}
CoPrtCnvRadioTelegram::~CoPrtCnvRadioTelegram()
{
if (m_BroadcastOnlyTelegram != nullptr)
ERROR_LOG(m_logger) << "Internal error: m_BroadcastOnlyTelegram was not nullptr while deletion of radio-telegram";
}
void CoPrtCnvRadioTelegram::setPayload1Byte(const uint8_t a_value)
{
set1Byte(m_data, m_PayloadIndex, a_value);
m_PayloadIndex += 1;
}
void CoPrtCnvRadioTelegram::setPayload2Byte(const uint16_t a_value)
{
setPayloadData(a_value, 2);
}
void CoPrtCnvRadioTelegram::setPayload3Byte(const uint32_t a_value)
{
setPayloadData(a_value, 3);
}
void CoPrtCnvRadioTelegram::setPayload4Byte(const uint32_t a_value)
{
setPayloadData(a_value, 4);
}
void CoPrtCnvRadioTelegram::setPayloadData(uint32_t a_value, const uint8_t a_size)
{
for (int i = m_PayloadIndex + a_size - 1; i >= m_PayloadIndex; i--)
{
set1Byte(m_data, i, a_value & 0xFF);
a_value >>= 8;
}
m_PayloadIndex += a_size;
}
void CoPrtCnvRadioTelegram::setPayloadData(const uint8_t *a_data, const uint16_t a_size)
{
uint8_t *ptr = reinterpret_cast<uint8_t *>(m_data.data());
memcpy(&ptr[m_PayloadIndex], a_data, a_size);
m_PayloadIndex += a_size;
}
void CoPrtCnvRadioTelegram::fixupTelegramIdForEts(bool convertToEtsId)
{
if (!s_etsMode)
return;
char *ptr = &m_data.data()[DATA_IND_REQ_HEADER_LENGTH];
if (convertToEtsId)
++(*ptr);
else
--(*ptr);
}
void CoPrtCnvRadioTelegram::setEtsMode(bool bIsEtsMode)
{
s_etsMode = bIsEtsMode;
}
gef_telegramm_id_et CoPrtCnvRadioTelegram::getTelID() const
{
return static_cast<gef_telegramm_id_et>(static_cast<uint8_t>(m_data.at(DATA_IND_REQ_HEADER_LENGTH)));
}
uint8_t CoPrtCnvRadioTelegram::zaehler() const
{
return static_cast<uint8_t>(m_data.at(1));
}
void CoPrtCnvRadioTelegram::setZaehler(const uint8_t a_counter)
{
set1Byte(m_data, 1, a_counter);
}
uint32_t CoPrtCnvRadioTelegram::getPayloadDataUInt32(size_t a_offset, uint16_t a_size) const
{
uint32_t value = 0;
const uint8_t *ptr = reinterpret_cast<const uint8_t *>(m_data.data());
uint8_t *ptrValue = reinterpret_cast<uint8_t *>(&value);
a_offset += DATA_IND_REQ_HEADER_LENGTH;
switch (a_size)
{
case 4:
ptrValue[3] = ptr[a_offset++];
Q_FALLTHROUGH();
case 3:
ptrValue[2] = ptr[a_offset++];
Q_FALLTHROUGH();
case 2:
ptrValue[1] = ptr[a_offset++];
Q_FALLTHROUGH();
case 1:
ptrValue[0] = ptr[a_offset++];
break;
default:
Q_ASSERT(false);
ERROR_LOG(m_logger) << "a_size must be between 1..4";
}
return value;
}
uint8_t CoPrtCnvRadioTelegram::getPayloadDataUInt8(size_t a_offset) const
{
return static_cast<uint8_t>(m_data.at(DATA_IND_REQ_HEADER_LENGTH + a_offset));
}
uint32_t CoPrtCnvRadioTelegram::getDestISSI() const
{
return getUInt32(9);
}
uint16_t CoPrtCnvRadioTelegram::getIdentity() const
{
return isLoginTelegram() ? getPayloadDataUInt32(0, 2) : getPayloadDataUInt32(1, 2);
}
void CoPrtCnvRadioTelegram::setSrcISSI(const uint32_t a_ISSI)
{
setSrcISSI_Internal(m_data, a_ISSI);
}
bool CoPrtCnvRadioTelegram::mustBroadcastBeSet() const
{
if (isNormalTelegram())
return getIdentity() == 0 && getBroadcastIndex() == 0;
return false;
}
void CoPrtCnvRadioTelegram::setBroadcastIndex(const uint16_t a_broadcastIndex)
{
set1Byte(m_data, DATA_IND_REQ_HEADER_LENGTH + 3, (a_broadcastIndex >> 8) & 0xFF);
set1Byte(m_data, DATA_IND_REQ_HEADER_LENGTH + 4, a_broadcastIndex & 0xFF);
}
void CoPrtCnvRadioTelegram::setDestISSI(const uint32_t a_ISSI)
{
setDestISSI_Internal(m_data, a_ISSI);
}
CoPrtCnvRadioTelegram::E_PDU_Type CoPrtCnvRadioTelegram::getPDU_Type() const
{
return static_cast<E_PDU_Type>(m_data.at(4));
}
CoPrtCnvRadioTelegram::E_FragmentStatus CoPrtCnvRadioTelegram::getFragmentStatus() const
{
return static_cast<E_FragmentStatus>(m_data.at(26) & e_FragmentStatusMask);
}
uint8_t CoPrtCnvRadioTelegram::getFragmentCounter() const
{
return static_cast<uint8_t>(m_data.at(26) & e_CounterMask);
}
bool CoPrtCnvRadioTelegram::isCrcOk() const
{
if ((m_data.at(26) & e_Checksum) == e_Checksum)
{
uint32_t sum = getProtocolIdentifier();
for (int i = DATA_IND_REQ_HEADER_LENGTH - PAYLOAD_STATUS_LENGTH; i < m_data.size() - 2; i++)
sum += static_cast<uint8_t>(m_data.at(i));
uint16_t checksum = getUInt8(m_data.size() - 2) * 256 + getUInt8(m_data.size() - 1);
checksum = ~checksum;
checksum++;
auto that = const_cast<CoPrtCnvRadioTelegram*>(this);
that->m_data.resize(m_data.size() - 2);
that->m_data[26] = (m_data.at(26) & ~e_Checksum);
if (sum != checksum)
{
ERROR_LOG(m_logger) << "Checksum of telegram is wrong: " << QString::number(checksum, 16)
<< " (expected: " << QString::number(sum, 16) << "), issi: " << getUInt32(5);
return true;
}
}
return true;
}
uint32_t CoPrtCnvRadioTelegram::getSrcISSI() const
{
return getUInt32(5);
}
bool CoPrtCnvRadioTelegram::isLoginTelegram() const
{
if (e_DataIndReq == getPDU_Type())
return (e_LoginTelegram == ((e_FragmentStatusMask | e_CounterMask) & m_data.at(26)));
return false;
}
bool CoPrtCnvRadioTelegram::mustBeFragmented() const
{
if (e_DataIndReq == getPDU_Type())
return size_t(getSize()) > (MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH + DATA_IND_REQ_WITH_TL_HEADER_LENGTH + sizeof(PrtCnvRadioGwHeader));
return false;
}
const uint8_t *CoPrtCnvRadioTelegram::getPayloadDataPtr(uint16_t a_offset) const
{
return reinterpret_cast<const uint8_t *>(&m_data.data()[DATA_IND_REQ_HEADER_LENGTH + a_offset]);
}
uint8_t *CoPrtCnvRadioTelegram::getPayloadDataPtr(uint16_t a_offset)
{
return reinterpret_cast<uint8_t *>(&m_data.data()[DATA_IND_REQ_HEADER_LENGTH + a_offset]);
}
uint16_t CoPrtCnvRadioTelegram::getPayloadSize() const
{
return static_cast<uint16_t>((getPDU_Type() == e_DataIndReq) ? m_data.size() - DATA_IND_REQ_HEADER_LENGTH : 0);
}
QByteArray CoPrtCnvRadioTelegram::getUnfragmentedData(const std::multimap<uint16_t, CoPrtCnvRadioTelegram *> &a_fragTelegramList)
{
NGL::INGLLogger &l = NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvRadioTelegram");
uint16_t totalSize = 0;
bool first = true;
uint8_t expectedNextFragment = 0;
CoPrtCnvRadioTelegram *firstFragment = nullptr;
std::multimap<uint16_t, CoPrtCnvRadioTelegram *>::const_reverse_iterator rit;
for (rit = a_fragTelegramList.rbegin(); rit != a_fragTelegramList.rend(); ++rit)
{
CoPrtCnvRadioTelegram *fragRadioTelegram = rit->second;
if (first)
{
if (e_FirstFragment == fragRadioTelegram->getFragmentStatus())
{
totalSize += fragRadioTelegram->getSize();
expectedNextFragment = fragRadioTelegram->getFragmentCounter() - 1;
firstFragment = fragRadioTelegram;
first = false;
}
else
{
ERROR_LOG(l) << "The fragment with the highest counter is not marked as first fragment";
return nullptr;
}
}
else
{
if (e_MiddleFragment == fragRadioTelegram->getFragmentStatus() || e_LastFragment == fragRadioTelegram->getFragmentStatus())
{
if (expectedNextFragment-- == fragRadioTelegram->getFragmentCounter())
{
if (e_LastFragment == fragRadioTelegram->getFragmentStatus() && 0 != fragRadioTelegram->getFragmentCounter())
{
ERROR_LOG(l) << "The last fragment must have a counter of 0, but the counter is " << (int)fragRadioTelegram->getFragmentCounter();
return nullptr;
}
totalSize += fragRadioTelegram->getPayloadSize();
}
else
{
ERROR_LOG(l) << "The fragmented Radio-Telegram from TNE with id=" << fragRadioTelegram->getIdentity() << " with fragment-counter=" << (expectedNextFragment + 1) << " was lost";
return nullptr;
}
}
else
{
ERROR_LOG(l) << "A fragment which is not the first one, is not marked as middle or last fragment";
return nullptr;
}
}
}
if (firstFragment
&& totalSize <= (DATA_IND_REQ_HEADER_LENGTH + MAX_NBR_OF_FRAGMENTS * (MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH - PAYLOAD_STATUS_LENGTH))
&& totalSize > DATA_IND_REQ_HEADER_LENGTH)
{
QByteArray data(totalSize, Qt::Uninitialized);
setHeader(data, e_DataIndReq);
fillDataIndReqHeader(data);
setSrcISSI_Internal(data, firstFragment->getSrcISSI());
setDestISSI_Internal(data, firstFragment->getDestISSI());
uint16_t index = DATA_IND_REQ_HEADER_LENGTH - PAYLOAD_STATUS_LENGTH;
set1Byte(data, index++, e_NotFragmented);
for (rit = a_fragTelegramList.rbegin(); rit != a_fragTelegramList.rend(); ++rit)
{
CoPrtCnvRadioTelegram *fragRadioTelegram = rit->second;
uint16_t fragSize = fragRadioTelegram->getPayloadSize();
if (index + fragSize <= totalSize)
{
memcpy(&data.data()[index], fragRadioTelegram->getPayloadDataPtr(0), fragSize);
index += fragSize;
}
else
{
ERROR_LOG(l) << "Internal error: size of allocated datablock is too small";
return QByteArray();
}
}
return data;
}
ERROR_LOG(l) << "Internal error while building unfragmented radio-telegram: fragTelegram=" << firstFragment << " totalSize=" << totalSize;
return QByteArray();
}
bool CoPrtCnvRadioTelegram::isTelegramLengthOk(const uint16_t a_lengthWithoutFrame)
{
return (a_lengthWithoutFrame <= (MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH + DATA_IND_REQ_HEADER_LENGTH - sizeof(PrtCnvRadioGwHeader) - PAYLOAD_STATUS_LENGTH));
}
bool CoPrtCnvRadioTelegram::isNormalTelegram() const
{
return (e_DataIndReq == getPDU_Type() && (e_NormalTelegram == ((e_FragmentStatusMask | e_CounterMask) & m_data.at(26))));
}
uint8_t CoPrtCnvRadioTelegram::getPriority() const
{
if (isNormalTelegram())
{
switch (getTelID())
{
case GEF_INIT:
case GEF_DEAKTIVIERUNG_EINZELMINE:
case GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG:
case GEF_SANITAETSDIENST_INSTANDSETZUNG:
case GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN:
return 2;
case GEF_WIRKFELD_EINZELGESCHOSS:
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER:
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP:
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN:
case GEF_WIRKFELD_MINENSPERRE:
case GEF_WIRKFELD_STATUS_MINENSPERRE:
case GEF_WIRKFELD_A_KAMPFMITTEL:
case GEF_WIRKFELD_C_KAMPFMITTEL:
case GEF_DEAKTIVIERUNG_WIRKFELD:
case GEF_REAKTIVIERUNG_DUS_MINE:
case GEF_TECHNIK_FUNKTIONSRAUM:
case GEF_FUNKTIONSRAUM:
case GEF_DEAKTIVIEREN_FUNKTIONSRAUM:
case GEF_DATENVERKEHR_TDS_GEOP:
case GEF_WIRKFELD_EINZELMINENSIMULATOR:
case GEF_POSITIONS_MELDUNG:
return 3;
case GEF_UMGEBUNGS_MELDUNG2:
case GEF_AUFFORDERUNG_BITE_MELDUNG:
case GEF_LIZENSIERUNG_TNE:
case GEF_TREFFER_AUSLOESUNG:
case GEF_SPRACHAUSWAHL:
case GEF_BESTANDSMELDUNG_SANITAETSMATERIAL:
case GEF_SELEKTIVE_AUFMUNITIONIERUNG:
case GEF_SCHIEDSRICHTERKOMMANDO:
return 4;
case GEF_KONFIGURATION_WIRKMODELL:
case GEF_ANFORDERUNG_KONFIGURATIONSDATEN:
case GEF_WIRKFELD_AENDERUNG_BEZEICHNER:
case GEF_DATENVERKEHR_TDS_SRT:
case GEF_DATENVERKEHR_TDS_DMF:
case GEF_DATENVERKEHR_TDS_TGTC:
case GEF_TEILNEHMERMODE_SETZEN:
case GEF_TEILNEHMER_KONFIG_ANFORDERN:
case GEF_TEILNEHMER_KONFIG_SETZEN:
return 5;
case GEF_ALLGEMEINE_NACHRICHT:
return 6;
case GEF_SW_VERSIONSMELDUNG:
return 7;
case GEF_NOP:
case GEF_WF_SAMMELDEAKTIVIERUNG:
case GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN:
case GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM:
return 99;
default:
ERROR_LOG(m_logger) << "Priority of telegram with telId=" << getTelID() << " not defined.";
#ifdef DEBUG
abort();
#endif
}
}
else if (isLoginTelegram())
return 4;
return 10;
}
uint16_t CoPrtCnvRadioTelegram::getBroadcastIndex() const
{
if (isNormalTelegram() && m_data.size() > (DATA_IND_REQ_HEADER_LENGTH + 4))
return getPayloadDataUInt32(3, 2);
return 0;
}
void CoPrtCnvRadioTelegram::setPayloadDataWithIndex(const uint16_t a_index, const uint32_t a_value, const uint16_t a_size)
{
if (1 == a_size)
set1Byte(m_data, DATA_IND_REQ_HEADER_LENGTH + a_index, a_value);
else
{
uint16_t savedPayloadIndex = m_PayloadIndex;
m_PayloadIndex = DATA_IND_REQ_HEADER_LENGTH + a_index;
setPayloadData(a_value, a_size);
m_PayloadIndex = savedPayloadIndex;
}
}
void CoPrtCnvRadioTelegram::setPayloadDataComplete(const QByteArray &payload)
{
m_data.resize(payload.size() + DATA_IND_REQ_HEADER_LENGTH);
setHeader(m_data, getPDU_Type());
memcpy(&m_data.data()[DATA_IND_REQ_HEADER_LENGTH], payload.data(), payload.size());
}
void CoPrtCnvRadioTelegram::resetPayloadSize(const uint16_t a_newPayloadSize)
{
m_data.resize(a_newPayloadSize + DATA_IND_REQ_HEADER_LENGTH);
setHeader(m_data, getPDU_Type());
uint16_t size = m_data.size();
set2Byte(m_data, 22, (size - DATA_IND_REQ_HEADER_LENGTH + PAYLOAD_STATUS_LENGTH) * 8);
set2Byte(m_data, 24, (size - DATA_IND_REQ_HEADER_LENGTH + PAYLOAD_STATUS_LENGTH));
}
void CoPrtCnvRadioTelegram::setIdentity(const uint16_t a_identity)
{
setPayloadDataWithIndex(isLoginTelegram() ? 0 : 1, a_identity, 2);
}
void CoPrtCnvRadioTelegram::setProtocolIdentifier(const E_ProtocolIdentifier a_ProtocolIdentifier)
{
if (e_DataIndReq == getPDU_Type())
set1Byte(m_data, 13, a_ProtocolIdentifier);
}
void CoPrtCnvRadioTelegram::setMessageReference(const uint8_t a_MessageReference)
{
if (isSDSTL())
set1Byte(m_data, 14, a_MessageReference);
}
bool CoPrtCnvRadioTelegram::isSDSTL() const
{
return (e_DataIndReq == getPDU_Type() && (e_UsingSDS_TL == (e_UsingSDS_TL & getProtocolIdentifier())));
}
CoPrtCnvRadioTelegram::E_RegistrationStatus CoPrtCnvRadioTelegram::getRegistrationStatus() const
{
return static_cast<E_RegistrationStatus>(m_data.at(5));
}
std::string CoPrtCnvRadioTelegram::getRegistrationStatusAsText() const
{
switch (getRegistrationStatus())
{
case e_IssiSuccessfulRegistered:
return "IssiSuccessfulRegistered";
case e_DuplicateISSI:
return "DuplicateISSI";
case e_InvalidISSI:
return "InvalidISSI";
case e_InvalidIpAddress:
return "InvalidIpAddress";
}
return std::to_string(getRegistrationStatus());
}
CoPrtCnvRadioTelegram::E_ProtocolIdentifier CoPrtCnvRadioTelegram::getProtocolIdentifier() const
{
return static_cast<E_ProtocolIdentifier>(m_data.at(13));
}
std::string CoPrtCnvRadioTelegram::getProtocolIdentifierAsText() const
{
switch (getProtocolIdentifier())
{
case e_SimpleTextMessagingWithoutSDS_TL:
return "Simple Text Messaging w/o SDS/TL";
case e_SimpleGPS_WithoutSDS_TL:
return "Simple GPS w/o SDS/TL";
case e_TDSMessageWithoutSDS_TL:
return "TDS Message w/o SDS/TL";
case e_UsingSDS_TL:
return "SDS/TL";
case e_SimpleTextMessagingUsingSDS_TL:
return "Simple Text Messaging with SDS/TL";
case e_SimpleGPS_UsingSDS_TL:
return "Simple GPS with SDS/TL";
case e_LoginTest:
return "Login-Test / Hohenfels";
}
return std::to_string(getProtocolIdentifier());
}
uint8_t CoPrtCnvRadioTelegram::getMessageReference() const
{
return static_cast<uint8_t>(m_data.at(14));
}
uint8_t CoPrtCnvRadioTelegram::getAreaSelection() const
{
return static_cast<uint8_t>(m_data.at(15));
}
uint8_t CoPrtCnvRadioTelegram::getValidityPeriod() const
{
return static_cast<uint8_t>(m_data.at(16));
}
uint32_t CoPrtCnvRadioTelegram::getForwardAddress() const
{
return getUInt32(17);
}
CoPrtCnvRadioTelegram::E_Flags CoPrtCnvRadioTelegram::getFlags() const
{
return static_cast<E_Flags>(m_data.at(21));
}
std::string CoPrtCnvRadioTelegram::getFlagsAsText() const
{
switch (getFlags())
{
case e_FlagsNone:
return "No Flags";
case e_StorageAllowed:
return "Storage Allowed";
case e_GroupServiceOrOnlyStandardReportAllowed:
return "Group Service or only Standard Report Allowed";
case e_ReceivedConfirmationRequested:
return "Received Confirmation Requested";
case e_ConsumedConfirmationRequested:
return "Consumed Confirmation Requested";
}
std::ostringstream str;
str << getFlags();
return str.str();
}
uint16_t CoPrtCnvRadioTelegram::getLengthInBits() const
{
return getUInt16(22);
}
uint16_t CoPrtCnvRadioTelegram::getLengthInBytes() const
{
return getUInt16(24);
}
bool CoPrtCnvRadioTelegram::getWithCrc() const
{
if (getSize() > 26)
return ((m_data.at(26) & e_Checksum) == e_Checksum);
return false;
}
CoPrtCnvRadioTelegram::E_DeliveryStatusForTL_Report CoPrtCnvRadioTelegram::getDelivery() const
{
return static_cast<E_DeliveryStatusForTL_Report>(m_data.at(16));
}
std::string CoPrtCnvRadioTelegram::getDeliveryAsText() const
{
switch (getDelivery())
{
case e_SDS_ReceiptAcknowledgedByDestination:
return "SDS receipt acknowledged by destination";
case e_SDS_ConsumedByDestination:
return "SDS consumed by destination";
case e_SourceIsNotAuthorizedForSDS:
return "Source is not authorized for SDS";
case e_DestinationIsNotAuthorizedForSDS:
return "Destination is not authorized for SDS";
case e_UnknownDestinationAddress:
return "Unknown destination address";
case e_DeliveryFailed:
return "Delivery failed";
case e_DestinationNotRegisteredOnSystem:
return "Destination not registered on system";
case e_DestinationQueueFull:
return "Destination queue full";
case e_MessageTooLong:
return "Message too long";
case e_DestinationHostPC_NotConnected:
return "Destination host PC not connected";
case e_ProtocolNotSupported:
return "Protocol not supported";
case e_DataCodingSchemeNotSupported:
return "Datat coding scheme not supported";
case e_DestinationNotReachable:
return "Destination not reachable";
}
std::ostringstream str;
str << getDelivery();
return str.str();
}
int32_t CoPrtCnvRadioTelegram::getPayloadDataSInt24(uint16_t a_offset) const
{
uint32_t value = getPayloadDataUInt32(a_offset, 3);
if (value & 0x800000)
value |= 0xFF800000;
return value;
}
bool CoPrtCnvRadioTelegram::needsLicensing() const
{
if (isNormalTelegram())
{
switch (getTelID())
{
case GEF_UMGEBUNGS_MELDUNG2:
case GEF_LIZENSIERUNG_TNE:
case GEF_AUFFORDERUNG_BITE_MELDUNG:
case GEF_ALLGEMEINE_NACHRICHT:
return false;
default:
break;
}
return true;
}
return false;
}
bool CoPrtCnvRadioTelegram::hasExpired() const
{
uint32_t expireTime = getExpireTime();
if (expireTime > 0)
{
uint32_t now = time(nullptr);
return (now >= expireTime);
}
return false;
}
uint32_t CoPrtCnvRadioTelegram::getExpireTime() const
{
if (isNormalTelegram())
{
uint32_t wirkBegin = 0;
uint32_t wirkDauer = 0;
switch (getTelID())
{
case GEF_WIRKFELD_EINZELGESCHOSS:
wirkBegin = getPayloadDataUInt32(11 + 5, 4);
wirkDauer = 5;
break;
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER:
wirkBegin = getPayloadDataUInt32(11 + 5, 4);
wirkDauer = getPayloadDataUInt32(15 + 5, 2);
break;
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN:
wirkBegin = getPayloadDataUInt32(11, 4);
wirkDauer = getPayloadDataUInt32(15, 2);
break;
case GEF_WIRKFELD_A_KAMPFMITTEL:
wirkBegin = getPayloadDataUInt32(11 + 5, 4);
wirkDauer = getPayloadDataUInt32(15 + 5, 2) * 60 * 10;
break;
case GEF_WIRKFELD_C_KAMPFMITTEL:
wirkBegin = getPayloadDataUInt32(11 + 5, 4);
wirkDauer = getPayloadDataUInt32(15 + 5, 1) * 60;
break;
case GEF_WIRKFELD_MINENSPERRE:
wirkBegin = getPayloadDataUInt32(11 + 5, 4);
wirkDauer = getPayloadDataUInt32(15 + 5, 1) * 60 * 60;
break;
default:
return 0;
}
if (0 == wirkDauer)
{
return 0;
}
if (wirkBegin > 0)
return (wirkBegin + wirkDauer);
}
return 0;
}
bool CoPrtCnvRadioTelegram::isContentValid()
{
if (isNormalTelegram())
{
uint16_t wirkfeldkennung = 0;
uint8_t wirkfeldtyp = 0;
switch (getTelID())
{
case GEF_WIRKFELD_EINZELGESCHOSS:
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER:
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP:
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN:
case GEF_WIRKFELD_MINENSPERRE:
case GEF_WIRKFELD_STATUS_MINENSPERRE:
case GEF_WIRKFELD_A_KAMPFMITTEL:
case GEF_WIRKFELD_C_KAMPFMITTEL:
case GEF_WIRKFELD_EINZELMINENSIMULATOR:
wirkfeldkennung = getPayloadDataUInt32(5, 2);
wirkfeldtyp = 3;
Q_FALLTHROUGH();
case GEF_DEAKTIVIERUNG_WIRKFELD:
case GEF_WIRKFELD_AENDERUNG_BEZEICHNER:
if (GEF_DEAKTIVIERUNG_WIRKFELD == getTelID() || GEF_WIRKFELD_AENDERUNG_BEZEICHNER == getTelID())
{
wirkfeldtyp = getPayloadDataUInt8(5);
wirkfeldkennung = getPayloadDataUInt32(6, 2);
}
if ((wirkfeldtyp >= 1 && wirkfeldtyp <= 5) || (wirkfeldtyp == 8))
{
if (wirkfeldkennung > 0 && wirkfeldkennung <= 32767)
return true;
ERROR_LOG(m_logger) << "Wirkfeldkennung (" << wirkfeldkennung << ") of telegram with telId=" << getTelID() << " is invalid. Must be 1..32768.";
return false;
}
if (GEF_WIRKFELD_AENDERUNG_BEZEICHNER == getTelID() && wirkfeldkennung > 0)
return true;
ERROR_LOG(m_logger) << "Wirkfeldtyp (" << wirkfeldtyp << ") of telegram with telId=" << getTelID() << " is invalid. Must be 1..5 or 8.";
return false;
case GEF_DEAKTIVIERUNG_EINZELMINE:
if (isPayloadLengthOk(13))
{
wirkfeldkennung = getPayloadDataUInt32(9, 2);
{
if (wirkfeldkennung > 32767)
{
ERROR_LOG(m_logger) << "DeaktivierungEinzelmine: wirkfeldkennung=" << wirkfeldkennung << " too big. Must be 1..32767";
return false;
}
}
return true;
}
return false;
case GEF_TECHNIK_FUNKTIONSRAUM:
case GEF_FUNKTIONSRAUM:
case GEF_DEAKTIVIEREN_FUNKTIONSRAUM:
{
uint32_t funktionsraumkennung = getPayloadDataUInt32(5, 2);
if (funktionsraumkennung > 0)
return true;
ERROR_LOG(m_logger) << "Funktionsraumkennung (" << funktionsraumkennung << ") of telegram with telId=" << getTelID() << " is invalid. Must be 1..65535.";
return false;
}
case GEF_EINTRETEN_FUNKTIONSRAUM:
if (isPayloadLengthOk(15))
{
uint32_t funktionsraumkennung = getPayloadDataUInt32(13, 2);
if (funktionsraumkennung > 0)
return true;
ERROR_LOG(m_logger) << "Funktionsraumkennung (" << funktionsraumkennung << ") of telegram with telId=" << getTelID() << " is invalid. Must be 1..65535.";
return false;
}
return false;
case GEF_SPRACHAUSWAHL:
{
uint8_t sprache = getPayloadDataUInt8(5);
if (sprache <= 3)
return true;
ERROR_LOG(m_logger) << "Sprache (" << sprache << ") of telegram with telId=" << getTelID() << " is invalid. Must be 0..3.";
return false;
}
case GEF_MANIPULATIONSMELDUNG:
return isPayloadLengthOk(12);
case GEF_BITE_MELDUNG2:
return isPayloadLengthOk(27, 19, 7);
case GEF_BETRIEBSZUSTAND_AUSSTATTUNG:
return isPayloadLengthOk(9);
case GEF_FEHLERMELDUNG_GFD:
return isPayloadLengthOk(9);
case GEF_POSITIONS_MELDUNG:
return isPayloadLengthOk(14);
case GEF_POSITIONS_MELDUNG_MIT_TEILNEHMER:
return isPayloadLengthOk(15, 14, 2);
case GEF_POSITIONS_MELDUNG_LFZ:
return isPayloadLengthOk(15);
case GEF_TREFFER_EREIGNIS_DUS:
return isPayloadLengthOk(23);
case GEF_TREFFER_EREIGNIS_WIRKSIMULATION:
return isPayloadLengthOk(22);
case GEF_SCHIEDSRICHTEREINGRIFF:
return isPayloadLengthOk(16);
case GEF_SELEKTIVE_AUFMUNITIONIERUNG:
return isPayloadLengthOk(8,7,8);
case GEF_TAKTISCHER_STATUS:
return isPayloadLengthOk(16);
case GEF_DATENVERKEHR_SRT_TDS:
case GEF_DATENVERKEHR_DMF_TDS:
{
uint16_t length = m_data.size() - DATA_IND_REQ_HEADER_LENGTH;
const uint16_t MIN_LENGTH = 7;
if (length >= MIN_LENGTH)
return true;
ERROR_LOG(m_logger) << "The payload-length of telegram with telId=" << getTelID() << " must be at least " << MIN_LENGTH << ", but it is only " << length;
return false;
}
case GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME:
return isPayloadLengthOk(10);
case GEF_SONDERSENSORIK_BETRIEBSZUSTAND:
return isPayloadLengthOk(9);
case GEF_SONDERSENSORIK_FAHRSPUR:
return isPayloadLengthOk(15);
case GEF_SONDERSENSORIK_DATEN:
return isPayloadLengthOk(17);
case GEF_SONDERSENSORIK_MIVANH_VERLEGEDATEN:
return isPayloadLengthOk(24);
case GEF_SONDERSENSORIK_WMIV_VERLEGEDATEN:
return isPayloadLengthOk(25);
case GEF_SONDERSENSORIK_MIVANH_VERLEGEPOSITION:
return isPayloadLengthOk(16);
case GEF_DATENVERKEHR_GEOP_TDS:
return isPayloadLengthOk(15, 14, 1);
case GEF_DATENVERKEHR_TGTC_TDS:
return isPayloadLengthOk(8, 7, 1);
case GEF_GERAETEEREIGNIS:
return isPayloadLengthOk(25, 24, 1);
case GEF_WAFFENZUORDNUNG:
return isPayloadLengthOk(8, 7, 6);
case GEF_MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE:
return isPayloadLengthOk(13, 12, 5);
case GEF_IPS_POSITIONSDATEN:
return isPayloadLengthOk(8, 7, 2);
case GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG:
return isPayloadLengthOk({13, 17});
case GEF_TEILNEHMERMODE_MELDUNG:
return isPayloadLengthOk(15);
case GEF_TEILNEHMER_KONFIG_ANTWORT:
return isPayloadLengthOk(27);
case GEF_DEFINITION_IED:
return isPayloadLengthOk(24);
case GEF_ZUSTAND_IED:
return isPayloadLengthOk(16);
case GEF_STATUS_EINZELMINENSIMULATOR:
return isPayloadLengthOk(17);
default:
break;
}
}
return true;
}
bool CoPrtCnvRadioTelegram::isPayloadLengthOk(uint16_t a_minLength,
const uint16_t a_dataAmountOffset,
const uint8_t a_variableDataElementSize) const
{
if (0 == a_variableDataElementSize)
return isPayloadLengthOk(a_minLength);
const uint16_t length = getPayloadSize();
if (length >= a_minLength)
{
uint8_t dataAmount = getPayloadDataUInt8(a_dataAmountOffset);
uint16_t dataSize = a_variableDataElementSize * dataAmount;
uint16_t expectedLength = dataSize + a_minLength;
if (expectedLength != length)
{
WARNING_LOG(m_logger) << "The payload-length of telegram with telId: "
<< getTelID() << " must be " << expectedLength
<< ", but it is " << length << " (the amount of variable data in telegram was "
<< dataAmount << " => " << dataSize << " bytes)";
return false;
}
}
else
{
WARNING_LOG(m_logger) << "The payload-length of telegram with telId: " << getTelID()
<< " must be at least " << a_minLength << ", but it is only " << length;
return false;
}
return true;
}
bool CoPrtCnvRadioTelegram::isPayloadLengthOk(uint16_t a_minLength,
uint16_t a_maxLength) const
{
if (a_maxLength == 0)
return isPayloadLengthOk(a_minLength);
const uint16_t length = getPayloadSize();
if (length < a_minLength)
{
WARNING_LOG(m_logger) << "The payload-length of telegram with telId: "
<< getTelID() << " must be greater or equal to "
<< a_minLength << ", but it is " << length;
return false;
}
if (length > a_maxLength)
{
WARNING_LOG(m_logger) << "The payload-length of telegram with telId: "
<< getTelID() << " must be fewer than "
<< a_minLength << ", but it is " << length;
return false;
}
return true;
}
bool CoPrtCnvRadioTelegram::isPayloadLengthOk(uint16_t a_length) const
{
const uint16_t length = getPayloadSize();
if (length == a_length)
return true;
WARNING_LOG(m_logger) << "The payload-length of telegram with telId: "
<< getTelID() << " must be "
<< a_length << ", but it is " << length;
return false;
}
bool CoPrtCnvRadioTelegram::isPayloadLengthOk(const std::vector<uint16_t> &a_lengths) const
{
const uint16_t length = getPayloadSize();
if (std::any_of(a_lengths.begin(), a_lengths.end(), [length](int len) { return len == length;}))
return true;
WARNING_LOG(m_logger) << "The payload-length of telegram with telId: "
<< getTelID() << ", is: " << length;
return false;
}
bool CoPrtCnvRadioTelegram::mustBeSentAsBroadcast(time_t a_currentTime, bool &a_wasLastBroadcast, const bool a_updateBroadcastCounter)
{
a_wasLastBroadcast = false;
if (m_BroadcastCounter < s_maxBroadcastSendCnt && m_NextSendTime <= a_currentTime)
{
if (a_updateBroadcastCounter)
{
switch (m_BroadcastCounter)
{
case 0:
if (s_2ndDelay >= 0)
{
m_NextSendTime = time(nullptr) + s_2ndDelay;
INFO_LOG(m_logger) << "1st Broadcast-Telegram telId=" << getTelID() << " BC=" << getBroadcastIndex();
break;
}
++m_BroadcastCounter;
Q_FALLTHROUGH();
case 1:
if (s_3rdDelay >= 0)
{
m_NextSendTime = time(nullptr) + s_3rdDelay;
INFO_LOG(m_logger) << "2nd Broadcast-Telegram telId=" << getTelID() << " BC=" << getBroadcastIndex();
break;
}
++m_BroadcastCounter;
Q_FALLTHROUGH();
default:
INFO_LOG(m_logger) << "3rd Broadcast-Telegram telId=" << getTelID() << " BC=" << getBroadcastIndex();
m_NextSendTime = 0;
a_wasLastBroadcast = true;
}
++m_BroadcastCounter;
}
return true;
}
return false;
}
void CoPrtCnvRadioTelegram::setBroadcastDelayTimes(int a_2ndDelay, int a_3rdDelay)
{
s_2ndDelay = a_2ndDelay;
s_3rdDelay = a_3rdDelay;
}
void CoPrtCnvRadioTelegram::setMaxBroadcastSendCnt(int a_maxSendCnt)
{
s_maxBroadcastSendCnt = a_maxSendCnt;
}
bool CoPrtCnvRadioTelegram::isMovedToBroadcastList() const
{
return (m_BroadcastCounter >= 1);
}
void CoPrtCnvRadioTelegram::setBroadcastOnly(const bool a_doSet)
{
m_IsBroadcastOnly = a_doSet;
}
bool CoPrtCnvRadioTelegram::isBroadcastOnly() const
{
return m_IsBroadcastOnly;
}
void CoPrtCnvRadioTelegram::setBroadcastonlyTelegram(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_radioTelegram)
{
if (a_radioTelegram != nullptr && m_BroadcastOnlyTelegram != nullptr)
ERROR_LOG(m_logger) << "Internal error: m_BroadcastOnlyTelegram was not nullptr";
if (a_radioTelegram != nullptr)
{
INFO_LOG(m_logger) << "Set braodcastonly-telegram: telId=" << a_radioTelegram->getTelID()
<< " BC=" << a_radioTelegram->getBroadcastIndex();
}
m_BroadcastOnlyTelegram = a_radioTelegram;
}
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> CoPrtCnvRadioTelegram::getBroadcastonlyTelegram() const
{
return m_BroadcastOnlyTelegram;
}
void CoPrtCnvRadioTelegram::set1Byte(QByteArray &a_data, uint16_t a_offset, uint8_t a_value)
{
Q_ASSERT(a_offset < a_data.size());
uint8_t *ptr = reinterpret_cast<uint8_t *>(&a_data.data()[a_offset]);
*ptr = a_value;
}
void CoPrtCnvRadioTelegram::set2Byte(QByteArray &a_data, uint16_t a_offset, uint16_t a_value)
{
Q_ASSERT(a_offset < a_data.size());
uint16_t *ptr = reinterpret_cast<uint16_t *>(&a_data.data()[a_offset]);
*ptr = a_value;
}
void CoPrtCnvRadioTelegram::set4Byte(QByteArray &a_data, uint16_t a_offset, uint32_t a_value)
{
Q_ASSERT(a_offset < a_data.size());
uint32_t *ptr = reinterpret_cast<uint32_t *>(&a_data.data()[a_offset]);
*ptr = a_value;
}
uint16_t CoPrtCnvRadioTelegram::getUInt16(const uint16_t a_offset) const
{
const uint16_t *ptr = reinterpret_cast<const uint16_t *>(&m_data.data()[a_offset]);
return *ptr;
}
uint32_t CoPrtCnvRadioTelegram::getUInt32(const uint16_t a_offset) const
{
const uint32_t *ptr = reinterpret_cast<const uint32_t *>(&m_data.data()[a_offset]);
return *ptr;
}
void CoPrtCnvRadioTelegram::setHeader(QByteArray &data, E_PDU_Type pduType)
{
set1Byte(data, 0, MAGIC_NUMBER);
set1Byte(data, 1, 0);
set2Byte(data, 2, data.size() - sizeof(PrtCnvRadioGwHeader));
set1Byte(data, 4, pduType);
}
void CoPrtCnvRadioTelegram::fillDataIndReqHeader(QByteArray &a_data)
{
set1Byte(a_data, 4, e_DataIndReq);
setSrcISSI_Internal(a_data, 0);
setDestISSI_Internal(a_data, 0);
set1Byte(a_data, 13, s_protocolIdentifier);
set1Byte(a_data, 14, 0);
set1Byte(a_data, 15, 0);
set1Byte(a_data, 16, 0);
set1Byte(a_data, 17, 0);
set1Byte(a_data, 18, 0);
set1Byte(a_data, 19, 0);
set1Byte(a_data, 20, 0);
set1Byte(a_data, 21, e_FlagsNone);
uint16_t size = a_data.size();
set2Byte(a_data, 22, (size - DATA_IND_REQ_HEADER_LENGTH + PAYLOAD_STATUS_LENGTH) * 8);
set2Byte(a_data, 24, (size - DATA_IND_REQ_HEADER_LENGTH + PAYLOAD_STATUS_LENGTH));
}
void CoPrtCnvRadioTelegram::setSrcISSI_Internal(QByteArray &data, const uint32_t issi)
{
set4Byte(data, 5, issi);
}
uint16_t CoPrtCnvRadioTelegram::getBroadcastCounter() const
{
return m_BroadcastCounter;
}
void CoPrtCnvRadioTelegram::setDestISSI_Internal(QByteArray &data, const uint32_t issi)
{
set4Byte(data, 9, issi);
}