Files
qt5-legatus-legacy/TetraIF/CoPrtCnv/CoPrtCnvRadioTelegram.hpp
T
2026-08-13 18:33:10 +02:00

883 lines
21 KiB
C++

// **************************************************************************
//
// (C) Copyright 2009 Swiss SIMTEC AG
//
// **************************************************************************
//
// $HeadURL$
// $LastChangedBy$
// $LastChangedDate$
// $LastChangedRevision$
//
// **************************************************************************
#pragma once
#include <set>
#include <map>
#include <memory>
#include <vector>
#include <QByteArray>
#include <CoPrtCnv/coprtcnv_export.h>
#include "tetra_telegram_ids.h"
namespace NGL
{
class INGLLogger;
}
namespace N_CoPrtCnv
{
/**
* used for telegram "LizenzierungTNE" to Radio
*/
enum class E_LicensingKind
{
/**
* Anmeldung erfolgreich
*/
Success = 0,
/**
* Anmeldung abgelehnt
*/
Rejected = 1,
/**
* Abmeldung
*/
Unlicense = 2
};
/**
* used for telegram "LizenzierungTNE" to Radio
*/
enum class E_LicensingErrorCode
{
Ok = 0,
Selftest = 1,
Battery = 2,
Configuration = 3,
Unlicense = 4,
IdentityDenied = 5
};
/**
* The radio-telegram, holds the data of telegram and additiional data for filling
* and sending as braodcast.
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:37:23
*/
class COPRTCNV_EXPORT CoPrtCnvRadioTelegram
{
public:
/**
* The radio-telegram flags
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:39:54
*/
enum E_Flags
{
e_FlagsNone = 0x00,
e_StorageAllowed = 0x10,
e_GroupServiceOrOnlyStandardReportAllowed = 0x20,
e_ReceivedConfirmationRequested = 0x40,
e_ConsumedConfirmationRequested = 0x80
};
/**
* The transmission-protocoll to be used for radio-telegram
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:39:54
*/
enum E_ProtocolIdentifier
{
e_SimpleTextMessagingWithoutSDS_TL = 0x02,
e_SimpleGPS_WithoutSDS_TL = 0x03,
e_TDSMessageWithoutSDS_TL = 0x50, // 80dec
e_UsingSDS_TL = 0x80,
e_SimpleTextMessagingUsingSDS_TL = 0x82,
e_SimpleGPS_UsingSDS_TL = 0x83,
e_LoginTest = 0x1D
};
/**
* The telegram-type:
* Fragmented, normal or login-telegram.
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:39:54
*/
enum E_FragmentStatus
{
e_NotFragmented = 0x00,
e_FirstFragment = 0x40,
e_MiddleFragment = 0xC0,
e_LastFragment = 0x80,
e_FragmentStatusMask = 0xC0,
e_Checksum = 0x20,
e_CounterMask = 0x0F,
e_NormalTelegram = 0x00,
e_LoginTelegram = 0x02,
e_DgpsTelegram = 0x03
};
/**
* The header of a radio-telegram
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:39:54
*/
struct PrtCnvRadioGwHeader
{
/**
* The first byte must be the magic number A5
*/
uint8_t m_MagicNumber;
/**
* The telegram-counter
*/
uint8_t m_Counter;
/**
* length of the following message in bytes
*/
uint16_t m_Length;
};
/**
* The PDU-type of radio-telegram
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:39:54
*/
enum E_PDU_Type
{
e_RegisterInd = 0,
e_RegisterRsp = 1,
e_DataIndReq = 2,
e_ReportIndReq = 3,
e_StatusIndReq = 4,
e_GroupMonitorReq = 6,
e_AirInterfaceLoadReq = 8,
e_AirLoadHyterra = 19
};
/**
* @author alois.wismer
* @version 1.0
* @created 17-Mrz-2010 13:06:40
*/
enum E_RegistrationStatus
{
e_IssiSuccessfulRegistered = 0,
e_DuplicateISSI = 1,
e_InvalidISSI = 2,
e_InvalidIpAddress = 3
};
/**
* The delivery-status (only for SDS-TL)
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:39:54
*/
enum E_DeliveryStatusForTL_Report
{
e_SDS_ReceiptAcknowledgedByDestination = 0x00,
e_SDS_ConsumedByDestination = 0x02,
e_SourceIsNotAuthorizedForSDS = 0x43,
e_DestinationIsNotAuthorizedForSDS = 0x44,
e_UnknownDestinationAddress = 0x45,
e_DeliveryFailed = 0x4A,
e_DestinationNotRegisteredOnSystem = 0x4B,
e_DestinationQueueFull = 0x4C,
e_MessageTooLong = 0x4D,
e_DestinationHostPC_NotConnected = 0x4F,
e_ProtocolNotSupported = 0x50,
e_DataCodingSchemeNotSupported = 0x51,
e_DestinationNotReachable = 0x5A
};
/**
* The status of the login-telegram
*
* @author wia
* @version 1.0
* @created 12-Mrz-2010 16:41:22
*/
enum E_LoginStatus
{
e_LoginRequest = 0x40,
e_LoginAccept = 0x80,
e_LoginReject = 0xC0,
e_LoginStatusMask = 0xC0,
e_LoginMastering = 0x20,
// Bits 2 & 3
e_LoginNoExerciseAssignment = 0x00, // none set
e_LoginOtherEqId = 0x02, // bit2 set
e_LoginOtherISSI = 0x04, // bit3 set
e_LoginOtherExercise = 0x06, // bit2+3 set
};
/**
* The first byte of the radio-telegram. Must be A5
*/
static constexpr uint8_t MAGIC_NUMBER = 0xA5;
/**
* length of a data-ind/req-telegram-header with TL and without the 4-byte frame-
* header.
* It contains PDUtype, SourceISSI, DestinationISSI, ProtocolIdentifier,
* LengthInBits and LengthInBytes. Payload-status is not included.
*/
static constexpr uint16_t DATA_IND_REQ_WITH_TL_HEADER_LENGTH = 22;
/**
* frameheader (4) + tetra-header (22) + payloadheader (1)
*/
static constexpr uint16_t DATA_IND_REQ_HEADER_LENGTH = 27;
/**
* frameheader (4) + tetra-header (22)
*/
static constexpr uint16_t DATA_IND_REQ_HEADER_LENGTH_WITHOUT_PAYLOAD_HEADER = DATA_IND_REQ_HEADER_LENGTH -1;
/**
* length of a data-ind/req-telegram-header without TL and without the 4-byte
* frame-header.
* It contains PDUtype, SourceISSI, DestinationISSI, ProtocolIdentifier,
* LengthInBits and LengthInBytes.
*/
static constexpr uint16_t DATA_IND_REQ_NO_TL_HEADER_LENGTH = 14;
/**
* the maximum length of payload-data (including payload-status-byte) of a radio-
* telegram. If payload-data is larger, fragmentation must be made.
*/
static constexpr uint16_t MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH = 249; // 256: 1 Byte Protokoll-ID + 255 Byte Daten
/**
* frameheader (4) + tetra-header (22) + payloadheader (1)
*/
static constexpr uint16_t PAYLOAD_STATUS_LENGTH = 1;
/**
* The protocol allows a max of 16 fragments, but due to definitions in file
* zsksxdit.x it could be less.
*/
static constexpr uint8_t MAX_NBR_OF_FRAGMENTS = 16;
/**
* constructor for a Register-Ind telegram
*
* @param a_sourceISSI
*/
explicit CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI);
/**
* constructor for a Group-Monitoring-Ind telegram
*
* @param a_sourceISSI
*/
explicit CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI, const std::set<uint32_t> &groups);
/**
* constructor for a Report-Ind telegram
*
* @param a_sourceISSI
* @param a_delivery
*/
explicit CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI, const E_DeliveryStatusForTL_Report a_delivery);
/**
* Constructor for received telegrams (Data-Ind/Req, PDU type = 2)
*
* @param a_data
*/
explicit CoPrtCnvRadioTelegram(const QByteArray &a_data);
/**
* the telegraminformation will be set
*
* @param a_telegramId
* @param a_payloadSize inclusive 3 byte telegraminformation
* @param a_identity
*/
explicit CoPrtCnvRadioTelegram(const gef_telegramm_id_et a_telegramId, const uint16_t a_payloadSize, const uint16_t a_identity);
/**
* for login-telegram
*
* @param a_loginTelegramStatus
* @param a_identity
* @param a_issi
*/
explicit CoPrtCnvRadioTelegram(const E_LoginStatus a_loginTelegramStatus, const uint16_t a_identity, uint32_t a_issi);
// set this issis for a login repsone e_LoginReject | e_LoginOtherExercise
void setLoginIssis(int hostIssi, int groupIssi1, int groupIssi2);
/**
* for generating fragmented telegrams.
* a_error will be true, if the fragmented telegrams cannot be generated.
*
* @param a_bigTelegram
* @param a_fragmentIndex
* @param a_error
*/
explicit CoPrtCnvRadioTelegram(const std::shared_ptr<CoPrtCnvRadioTelegram> &a_bigTelegram,
const uint8_t a_fragmentIndex, bool &a_error);
virtual ~CoPrtCnvRadioTelegram();
/**
* ETS Hack due to +/-1 telegram id on tetra ...
*/
void fixupTelegramIdForEts(bool convertToEtsId);
static void setEtsMode(bool bIsEtsMode);
/**
* Sets the paylaod-data.
*
* @param a_value
* @param a_size
*/
void setPayload1Byte(uint8_t a_value);
void setPayload2Byte(uint16_t a_value);
void setPayload3Byte(uint32_t a_value);
void setPayload4Byte(uint32_t a_value);
void setPayloadData(uint32_t a_value, const uint8_t a_size);
/**
* Sets the paylaod-data.
*
* @param a_value
*/
void setPayloadData(const uint8_t a_value) { return setPayload1Byte(a_value); }
/**
* Sets the paylaod-data.
*
* @param a_data
* @param a_size
*/
void setPayloadData(const uint8_t *a_data, const uint16_t a_size);
/**
* Returns a pointer to data of radio-telegram.
*/
const char *getData() const { return m_data.data(); }
char *getData() { return m_data.data(); }
QByteArray data() const { return m_data; }
/**
* the overall size of telegram, including all headers
*/
int getSize() const { return m_data.size(); }
/**
* Returns the telegramId of radio-telegram.
*/
gef_telegramm_id_et getTelID() const;
/**
* Returns the counter.
*/
uint8_t zaehler() const;
/**
* Sets the counter.
*
* @param a_counter
*/
void setZaehler(const uint8_t a_counter);
/**
* Returns a paylaod-value. Its size depends on a_size.
*
* @param a_offset
* @param a_size
*/
uint32_t getPayloadDataUInt32(size_t a_offset, uint16_t a_size) const;
/**
* Returns a 1-byte paylaod-value.
*
* @param a_offset
*/
uint8_t getPayloadDataUInt8(size_t a_offset) const;
/**
* Returns the destISSI of radio-telegram.
*/
uint32_t getDestISSI() const;
/**
* Returns the identiy of radio-telegram.
*/
uint16_t getIdentity() const;
/**
* Sets the srcISSI.
*
* @param a_ISSI
*/
void setSrcISSI(const uint32_t a_ISSI);
/**
* Returns true if it is broadcast-telegram, which has not yet set a broadcast-
* index.
*/
bool mustBroadcastBeSet() const;
/**
* Sets the broadcast-index.
*
* @param a_broadcastIndex
*/
void setBroadcastIndex(const uint16_t a_broadcastIndex);
/**
* Set the dstISSI.
*
* @param a_ISSI
*/
void setDestISSI(const uint32_t a_ISSI);
/**
* Returns the PDU-type of radio-telegram.
*/
CoPrtCnvRadioTelegram::E_PDU_Type getPDU_Type() const;
/**
* Returns the fragment-status of radio-telegram.
*/
CoPrtCnvRadioTelegram::E_FragmentStatus getFragmentStatus() const;
/**
* Returns the fragment-counter of radio-telegram.
*/
uint8_t getFragmentCounter() const;
/**
* If CRC-bit is set, it checks the CRC and removes CRC-stuff from telegram.
* If CRC-bit is not set, simply true will be returned
*/
bool isCrcOk() const;
/**
* Returns the srcISSI of radio-telegram.
*/
uint32_t getSrcISSI() const;
/**
* returns true if the it is a special login telegram
*/
bool isLoginTelegram() const;
/**
* returns true if the it is a special login telegram
*/
bool mustBeFragmented() const;
/**
* Returns a pointer to payload-data on a certain position of radio-telegram.
*
* @param a_offset
*/
const uint8_t *getPayloadDataPtr(uint16_t a_offset) const;
uint8_t *getPayloadDataPtr(uint16_t a_offset);
/**
* the size of payload-data without payload-status-header
*/
virtual uint16_t getPayloadSize() const;
/**
* Converts the list of fragmented telegrams into 1 big radio-telegram.
* The function allocates a block of data. The caller is responsible to delete
* this block of data, when no longer used.
* If conversion fails NULL will be returned
*
* @param a_fragTelegramList
*/
static QByteArray getUnfragmentedData(const std::multimap<uint16_t, CoPrtCnvRadioTelegram *> &a_fragTelegramList);
/**
* length without frame-header (4 byte)
*
* @param a_lengthWithoutFrame
*/
static bool isTelegramLengthOk(const uint16_t a_lengthWithoutFrame);
/**
* returns true if the it is a normal, unfragmented telegram (but not a login-
* telegram)
*/
bool isNormalTelegram() const;
/**
* Returns the priority of radio-telegram.
*/
uint8_t getPriority() const;
/**
* Returns the broadcast-index of radio-telegram.
*/
uint16_t getBroadcastIndex() const;
/**
* Sets the paylaod-data based on a_index with size a_size.
*
* @param a_index the payload-based position where the byte should be written
* @param a_value
* @param a_size
*/
void setPayloadDataWithIndex(const uint16_t a_index, const uint32_t a_value, const uint16_t a_size);
/**
* Sets the complete paylaod-data.
*
* @param a_data
* @param a_length
*/
void setPayloadDataComplete(const QByteArray &payload);
/**
* ATTENTION with use of this function, because it is a (little) dirty trick to
* resize the sammel-telegrams without memory-allocation.
* It is the responsibity of the user to not overwrite memory!!!
*
* @param a_newPayloadSize
*/
void resetPayloadSize(const uint16_t a_newPayloadSize);
/**
* Set the identity.
*
* @param a_identity
*/
void setIdentity(const uint16_t a_identity);
/**
* Sets the protocol-identifier.
*
* @param a_ProtocolIdentifier
*/
void setProtocolIdentifier(const E_ProtocolIdentifier a_ProtocolIdentifier);
/**
* Sets the message-reference.
*
* @param a_MessageReference
*/
void setMessageReference(const uint8_t a_MessageReference);
/**
* returns true if the it is a SDS/TL telegram
*/
bool isSDSTL() const;
/**
* Returns the registration-status of TETRA-header of SdsGw-Register-Rsp telegram
*/
CoPrtCnvRadioTelegram::E_RegistrationStatus getRegistrationStatus() const;
/**
* Returns the registration-status of TETRA-header of SdsGw-Register-Rsp telegram
* in text-form
*/
std::string getRegistrationStatusAsText() const;
/**
* Returns the protocolIdentifier of radio-telegram.
*/
CoPrtCnvRadioTelegram::E_ProtocolIdentifier getProtocolIdentifier() const;
/**
* Returns the protocolIdentifier of radio-telegram in text-form
*/
std::string getProtocolIdentifierAsText() const;
/**
* Returns the message-reference of radio-telegram.
*/
uint8_t getMessageReference() const;
/**
* Returns the area selection of TETRA-Header
*/
uint8_t getAreaSelection() const;
/**
* Returns the validity period of radio-telegram.
*/
uint8_t getValidityPeriod() const;
/**
* Returns the forward-address of TETRA-Header
*/
uint32_t getForwardAddress() const;
/**
* Returns the flags of TETRA-Header
*/
CoPrtCnvRadioTelegram::E_Flags getFlags() const;
/**
* Returns the flags of TETRA-Header as text
*/
std::string getFlagsAsText() const;
/**
* Returns the length in bits-field of TETRA-Header
*/
uint16_t getLengthInBits() const;
/**
* Returns the length in bytes-field of TETRA-Header
*/
uint16_t getLengthInBytes() const;
/**
* Returns true when the Telegram has a crc checksum.
*/
bool getWithCrc() const;
/**
* Returns the delivery-field of TETRA-Header of SdsGw-Report-Ind/Req telegrams.
*/
CoPrtCnvRadioTelegram::E_DeliveryStatusForTL_Report getDelivery() const;
/**
* Returns the delivery-field of TETRA-Header of SdsGw-Report-Ind/Req telegrams as
* text.
*/
std::string getDeliveryAsText() const;
/**
* Converts a signed 3-byte value into a signed 4-byte-value. I.e. used for
* positions (north and east).
*
* @param a_offset
*/
int32_t getPayloadDataSInt24(uint16_t a_offset) const;
/**
* Returns true if the telegram needs licensing.
*/
bool needsLicensing() const;
/**
* returns true when the telegram has an expiry-date and is expired.
* Returns false if the telegram has no expiry-date
*/
bool hasExpired() const;
/**
* Returns the expire-time of the telegram.
* Returns 0 if the telegram has not expire-time.
*/
uint32_t getExpireTime() const;
/**
* checks whether the content of telegram is valid, but only a few data will be
* checked, i.e. the kennung of wirkfeld and funktionsraum.
* Returns true if content of telegram is vaild (or will not be checked)
*/
bool isContentValid();
/**
* returns true if it is time to send this telegram as normal broadcast.
*
* @param a_currentTime
* @param a_wasLastBroadcast
* @param a_updateBroadcastCounter
*/
bool mustBeSentAsBroadcast(time_t a_currentTime, bool &a_wasLastBroadcast, const bool a_updateBroadcastCounter = true);
/**
* Set the delay-times for 2nd and 3rd broadcast.
*
* @param a_2ndDelay
* @param a_3rdDelay
*/
static void setBroadcastDelayTimes(int a_2ndDelay, int a_3rdDelay);
/**
* Set the max count of how often a Broadcasttelegram will be send (0 is ignored, the telegram is send at least one time.
*
* @brief setMaxBroadcastSendCnt
* @param a_maxSendCnt
*/
static void setMaxBroadcastSendCnt(int a_maxSendCnt);
/**
* returns true if it is a broadcast-telegram and it is moved to broadcast-list
*/
bool isMovedToBroadcastList() const;
/**
* Sets the broadcast-only-flag.
*
* @param a_doSet
*/
void setBroadcastOnly(const bool a_doSet = true);
/**
* Returns the broadcast-only-flag.
*/
bool isBroadcastOnly() const;
/**
* Defines the telegram which will be sent as normal broadcast instead a
* Sammeltelegram.
*
* @param a_radioTelegram
*/
void setBroadcastonlyTelegram(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_radioTelegram);
/**
* Returns the telegram which will be sent as normal broadcast instead a
* Sammeltelegram.
*/
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> getBroadcastonlyTelegram() const;
/**
* nbr of times already sent this normal broadcast (only used for broadcast-
* telegrams)
*/
uint16_t getBroadcastCounter() const;
//begin_public_{ACFD8558-E5A4-4877-B503-41FCB730B678}
//end_public_{ACFD8558-E5A4-4877-B503-41FCB730B678}
protected:
/**
* The telegram-data, including header
*/
QByteArray m_data;
/**
* The internal index for filling telegram with setPayloadData()
*/
uint16_t m_PayloadIndex;
/**
* nbr of times already sent this normal broadcast (only used for broadcast-
* telegrams)
*/
uint16_t m_BroadcastCounter;
/**
* time when sending next normal broadcast (only used for broadcast-telegrams)
*/
time_t m_NextSendTime;
/**
* The delay between 1st and 2nd normal broadcast
*/
static int s_2ndDelay;
/**
* The delay between 2nd and 3rd normal broadcast
*/
static int s_3rdDelay;
/**
* The delay between 2nd and 3rd normal broadcast
*/
static int s_maxBroadcastSendCnt;
/**
* True if the telegram is used only as normal broadcast, not as nachforderung
*/
bool m_IsBroadcastOnly;
/**
* Contains the normal broadcast-telegram, which will be sent instead of
* sammeltelegram for Nachfoderung
*/
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> m_BroadcastOnlyTelegram;
/**
* For ETS - there al telgram ids are +1, therefore we have to remove 1 to be able
* to work with our ids.
*/
static bool s_etsMode;
/**
* checks the payload-length of telegram. Returns true if the length is ok.
* Logs an error if length not ok.
*/
bool isPayloadLengthOk(uint16_t a_minLength,
const uint16_t a_dataAmountOffset,
const uint8_t a_variableDataElementSize) const;
bool isPayloadLengthOk(uint16_t a_minLength,
uint16_t a_maxLength) const;
bool isPayloadLengthOk(uint16_t a_length) const;
bool isPayloadLengthOk(const std::vector<uint16_t> &a_lengths) const;
/**
* Set a 1-byte value at offset a_offset.
*/
static void set1Byte(QByteArray &a_data, uint16_t a_offset, uint8_t a_value);
/**
* Set a 2-byte value at offset a_offset.
*/
static void set2Byte(QByteArray &a_data, uint16_t a_offset, uint16_t a_value);
/**
* Set a 4-byte value at offset a_offset.
*/
static void set4Byte(QByteArray &a_data, uint16_t a_offset, uint32_t a_value);
uint8_t getUInt8(const uint16_t a_offset) const { return static_cast<uint8_t>(m_data.at(a_offset)); }
uint16_t getUInt16(const uint16_t a_offset) const;
uint32_t getUInt32(const uint16_t a_offset) const;
/**
* Sets the header with magic-number and size. The length will be 0.
*
* @param a_data
* @param a_size The overall-size including all headers
*/
static void setHeader(QByteArray &data, E_PDU_Type pduType);
/**
* Fills the header with SrcISSI, DstISSI, length in bits and length in bytes. PDU
* will be set for DataIndicationRequest.
* ProtocolIdentifier, message reference, area selection, forward address, flags
* will be filled with default-values.
*
* @param a_data
*/
static void fillDataIndReqHeader(QByteArray &a_data);
/**
* Internal function to set the srcISSI.
*
* @param a_data
* @param a_ISSI
*/
static void setSrcISSI_Internal(QByteArray &data, const uint32_t issi);
/**
* Internal function to set the dstISSI.
*
* @param a_data
* @param a_ISSI
*/
static void setDestISSI_Internal(QByteArray &data, const uint32_t issi);
private:
/**
* The logger object
*/
NGL::INGLLogger &m_logger;
};
}