// ************************************************************************** // // (C) Copyright 2009 Swiss SIMTEC AG // // ************************************************************************** // // $HeadURL$ // $LastChangedBy$ // $LastChangedDate$ // $LastChangedRevision$ // // ************************************************************************** #pragma once #include "LogViewXdrStandardType.hpp" #include "LogViewField.hpp" #include #include #include #include namespace N_CoPrtCnv { class CoPrtCnvRadioTelegram; } namespace N_LogView { struct StructInformation; struct MemberInformation; class LogViewTetraTelegramsParser; class LogViewXdrParser; class LogViewXdrType; /** * The header and the data of a logged or a edited telegram. * * Writing telegrams: * 1. allocate a telegram with the constructor LogViewTelegram(N_CoPrtCnv:: * CoPrtCnvLogHeader::e_DestProtocolCentral, telegramId) * 2. prepare with resetOffset() * 3. write data with setUIntX() * 4. finish with setNewSize(); * * @author alois.wismer * @version 1.0 * @created 04-Feb-2010 13:15:43 */ class LogViewTelegram final { public: /** * @author alois.wismer * @version 1.0 * @created 12-Mrz-2010 11:04:14 */ enum E_Validity { e_NotYetEvaluated, e_Valid, e_Invalid }; /** * @author alois.wismer * @version 1.0 * @created 05-Mai-2010 09:07:22 */ enum E_Column { e_ColName, e_ColGpsTime, e_ColLogTime, e_ColJsonData, e_ColMax }; ~LogViewTelegram(); /** * The size of the field which defines the size of the dyn. array for central- * telegrams */ static const uint16_t SIZE_CENTRAL_DYN_ARRAY_SIZE; /** * Copy ctor */ LogViewTelegram(const LogViewTelegram &o); // no assignment (needed) LogViewTelegram &operator=(const LogViewTelegram &o) = delete; /** * Constructor for new telegrams (only receive central-telegrams are allowd), * which will be edited * * @param a_destination * @param a_telId */ LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol a_destination, int telegramId); /** * Constructor for existing telegrams * * @param a_destination * @param a_unixTime * @param a_telegramData * @param a_telegramSize */ LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol a_destination, const quint64 a_unixTime, const QByteArray &a_telegramData); /** * Writes a_value with size a_size at actual position of m_Data (given with * m_ActOffset). m_ActOffset will be updated after writing data. * If the size of m_Data is not big enough, it will be made bigger. * * @param a_size * @param a_value * @param a_byteOrder */ void setUIntX(const uint8_t a_size, quint64 a_value, const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian); /** * Returns true if a_data could be written. * Returns false if a_offset is outside of range and therefore a_data could not be * written. * * @param a_offset * @param a_data */ bool setData(const uint16_t a_offset, const uint8_t a_data); /** * Returns the log-time of the telegram */ quint64 getLogTime() const { return m_LogTime; } quint64 getLogTimeMsec() const; /** * Returns the log-time of the telegram as pretty formatted text */ QString getLogTimeText() const; QString getDestinationText() const; /** * Returns the gps-time of the telegram */ quint64 getGpsTime() const { return m_GpsTime; } /** * Returns the GPS-time of the telegram as pretty formatted text. Only telegrams * from TETRA to central have a GPS-time, for all other telegrams an empty string * will be returned. */ QString getGpsTimeText() const; uint32_t getISSI() const { return m_ISSI; } int getParticipantId() const { return m_ParticipantId; } /** * Returns the difference between GPS-time and log-time in seconds. Only telegrams * from TETRA to central have a GPS-time (and therefore only for this telegrams a * time-difference can be calculated), for all other telegrams 0 will be returned. */ int32_t getDelay() const; /** * Returns the tool-tip text for the with a_col defined column for this telegram. * Its content depends on the type and subtype of telegram. * * @param a_col */ QString getToolTipText(const E_Column a_col); void resetOffset(); LogViewField* getFieldTree(); void dump() const; QString getStructName() const; bool isValid(); N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol getDestination() const { return m_Destination; } N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol getDirection() const; N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol getProtocol() const { return m_Protocol; } int getTelId() const { return m_TelId; } QIcon getIcon() const; bool isJsonTelegram() const { return N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral == m_Protocol; } void clearJsonData() { m_json.remove(QStringLiteral("data")); } void rebuildJsonString() { if (!m_json.isEmpty()) m_data.clear(); } void setJsonValue(const QStringList &path, const QJsonValue &val); QJsonObject jsonData() const { return m_json; } void updateJsonValue(const QStringList &path, const QJsonValue &newVal, QJsonObject &obj); void updateJsonValue(const QStringList &path, const QJsonValue &newVal, QJsonArray &arr); const N_CoPrtCnv::CoPrtCnvRadioTelegram* getTetraTelegram() const; static LogViewTetraTelegramsParser *jsonParser(); static LogViewXdrParser *tetraParser(); QByteArray getData(QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Compact) const; /** * The time to wait after sending this telegram in milliseconds. */ uint32_t getWaitTime() const { return m_WaitTime; } /** * The time to wait after sending this telegram in milliseconds. * * @param newVal */ void setWaitTime(uint32_t newVal) { m_WaitTime = newVal; } /** * The name of the telegram, shown in edit-list */ QString getName() const { return m_Name; } /** * The name of the telegram, shown in edit-list * * @param newVal */ void setName(const QString &newVal) { m_Name = newVal; } void setNextFieldAsGpsTimeField(); QVector getGpsTimeField() const { return m_GpsFieldOffset; } void setGpsTimeField(const QVector &gpsFieldOffset) { m_GpsFieldOffset = gpsFieldOffset; } void actualizeGpsTime(); /** * Create the tooltip text for the column 'Name' */ void createToolTipTextForColName(); static double xdrToDouble(quint64 in); static float xdrToFloat(uint32_t in); static quint64 doubleToXdr(double in); static uint32_t floatToXdr(float in); protected: /** * The name of the telegram, shown in edit-list */ QString m_Name; /** * The tooltip text for caching purposes */ std::vector m_ToolTipText; /** * The time to wait after sending this telegram in milliseconds. */ uint32_t m_WaitTime; int m_ParticipantId; /** * The ISSI of TETRA-Protocol */ uint32_t m_ISSI; /** * The allocated size of m_Data. (Used for optimizing of speed) */ int m_AllocatedSize; static const LogViewXdrParser* m_Parser; uint16_t m_ActOffset; QVector m_GpsFieldOffset; int m_TelId; /** * used for dyn. array in TETRA-Protocol */ uint32_t m_LastUnsignedValue; /** * This value will be used for the dyn-array-method e_DynArrayMsgLength. This * value will be subtracted from the message-length to get the size of the dynamic * array. */ uint16_t m_MaxArraySize; static const uint16_t START_OFFSET_CENTRAL; static const uint16_t POS_CENTRAL_COUNTER; static const uint16_t POS_CENTRAL_TELID; static const uint16_t POS_CENTRAL_PARTICIPANTID; static const uint16_t START_OFFSET_TETRA_REGISTER; static const uint16_t START_OFFSET_TETRA_AIRLOAD; static const uint16_t START_OFFSET_TETRA_DATA; static const uint16_t START_OFFSET_TETRA_LOGIN; static const uint16_t START_OFFSET_TETRA_FRAGMENT; LogViewXdrStandardType::E_DynArraySizeMethod m_DynArraySizeMethod; N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol m_Destination; E_Validity m_Validity; N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol m_Protocol; quint64 m_LogTime; mutable QString m_logTimeText; quint64 m_GpsTime; QByteArray m_data; QJsonObject m_json; N_CoPrtCnv::CoPrtCnvRadioTelegram *m_TetraTelegram; LogViewField *getFieldTree(const QString& a_type, const QString& a_name, uint16_t a_arraySize, const LogViewXdrType* a_parentElement = nullptr, const bool a_hasContent = true); LogViewField *getFieldTreeJson(const QJsonValue &data, const QString &name, const StructInformation &si, const QStringList &objectPathBase); static void addFieldTreeStruct(const QJsonObject &parentObject, LogViewField *parent, const StructInformation &si, const QString &objectNameArrayHint, NGL::INGLLogger &logger); static void addFieldTreeJsonString(const QJsonValue &val, LogViewField *parent, const QString &name, bool isBinary, const QString &objectNameArrayHint, LogViewField::E_FieldKind fieldKind, NGL::INGLLogger &logger); static void addFieldTreeJsonPod(const QJsonValue &val, LogViewField *parent, const QString &name, const QString &type, const QString &objectNameArrayHint, LogViewField::E_FieldKind fieldKind, NGL::INGLLogger &logger); static void addFieldTreeJsonEnum(const QJsonValue &val, LogViewField *parent, const QString &name, const QString &type, const QString &objectNameArrayHint, LogViewField::E_FieldKind fieldKind, NGL::INGLLogger &logger); static QString typeFromStructInformation(const StructInformation &si, const QString &name); static MemberInformation memberFromStructInformation(const StructInformation &si, const QString &name); /** * * @param a_offset */ uint16_t getUInt16(const uint16_t a_offset) const; /** * * @param a_offset */ uint32_t getUInt32(const uint16_t a_offset) const; /** * * @param a_offset */ int32_t getInt32(const uint16_t a_offset) const; /** * * @param a_offset * @param a_size * @param a_byteOrder */ quint64 getUIntX(const uint16_t a_offset, const uint8_t a_size, const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian) const; /** * * @param a_offset * @param a_size * @param a_byteOrder */ int32_t getSIntX(const uint16_t a_offset, const uint8_t a_size, const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian) const; /** * * @param a_offset * @param a_size */ char getChar(const uint16_t a_offset, const uint8_t a_size) const; /** * * @param a_standardType * @param a_offset * @param a_arraySize */ LogViewField* getContent(const LogViewXdrStandardType* a_standardType, uint16_t& a_offset, const uint16_t a_arraySize); /** * * @param a_xdrType */ bool isScalar(const LogViewXdrType* a_xdrType) const; /** * * @param a_errorText * @param a_title */ void showMessageBox(const QString& a_errorText, const QString& a_title = QObject::tr("Invalid telegram")) const; /** * * @param a_offset */ uint16_t getDynArraySize(uint16_t& a_offset) const; /** * * @param a_name * @param a_value */ static QString formatToolTipLine(const QString& a_name, const uint32_t a_value) { return formatToolTipLine(a_name, QString::number(a_value), a_value); } /** * * @param a_name * @param a_text * @param a_value */ static QString formatToolTipLine(const QString& a_name, const QString& a_text, const uint32_t a_value); static QString formatToolTipLine(const QString& a_name, const std::string& a_text, const uint32_t a_value) { return formatToolTipLine(a_name, QString::fromStdString(a_text), a_value); } /** * returns the data-byte at a_offset. Returns 0 if a_offset is outside of range. * * @param a_offset */ uint8_t getData(const uint16_t a_offset) const; private: /** * The logger object */ NGL::INGLLogger &m_logger; friend class LogViewTabWidget; }; }