File: dbc_classes.h

package info (click to toggle)
savvycan 220-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,456 kB
  • sloc: cpp: 61,803; sh: 293; javascript: 91; python: 44; makefile: 8
file content (190 lines) | stat: -rw-r--r-- 5,533 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#ifndef DBC_CLASSES_H
#define DBC_CLASSES_H

#include <QColor>
#include <QString>
#include <QStringList>
#include <QVariant>
#include "can_structs.h"

/*classes to encapsulate data from a DBC file. Really, the stuff of interest
  are the nodes, messages, signals, attributes, and comments.

  These things sort of form a hierarchy. Nodes send and receive messages.
  Messages are comprised of signals. Nodes, signals, and messages potentially have attribute values.
  All of them can have comments.
*/

enum DBC_SIG_VAL_TYPE
{
    UNSIGNED_INT,
    SIGNED_INT,
    SP_FLOAT,
    DP_FLOAT,
    STRING
};

enum DBC_ATTRIBUTE_VAL_TYPE
{
    ATTR_INT,
    ATTR_FLOAT,
    ATTR_STRING,
    ATTR_ENUM,
};

enum DBC_ATTRIBUTE_TYPE
{
    ATTR_TYPE_GENERAL,
    ATTR_TYPE_NODE,
    ATTR_TYPE_MESSAGE,
    ATTR_TYPE_SIG,
    ATTR_TYPE_ANY
};

class DBC_ATTRIBUTE
{
public:
    QString name;
    DBC_ATTRIBUTE_VAL_TYPE valType;
    DBC_ATTRIBUTE_TYPE attrType;
    double upper, lower;
    QStringList enumVals;
    QVariant defaultValue;
};

class DBC_ATTRIBUTE_VALUE
{
public:
    QString attrName;
    QVariant value;
};

class DBC_VAL_ENUM_ENTRY
{
public:
    int value;
    QString descript;
};

class DBC_NODE
{
public:
    QString name;
    QString comment;
    QString sourceFileName;
    QList<DBC_ATTRIBUTE_VALUE> attributes;

    DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
    DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);

    friend bool operator<(const DBC_NODE& l, const DBC_NODE& r)
    {
        return (l.name.toLower() < r.name.toLower());
    }
};

class DBC_MESSAGE; //forward reference so that DBC_SIGNAL can compile before we get to real definition of DBC_MESSAGE
class DBC_SIGNAL;

/*
 * Both DBC_SIGNAL and DBC_MESSAGE used to use a lot of pointers. This worked in QT5 because QList was
 * sort of a linked list. It was a QVector that stores pointers to objects on the heap. Since those
 * objects would not move this allowed for taking pointers to them. However, QT6 causes a problem here
 * as now QVector and QList are the exact same and both store items actually in the list, not as pointers.
 * This causes invalidation any time a size modifying call is done on the QVector/QList.
 * So, the easiest solution to keep the code mostly the same and things working like they did
 * is to re-introduce pointers with smart pointers.
 *
*/

class DBC_SIGNAL
{
public: //TODO: Clean up this class so that not everything is public. There is one private member which is a start...
    DBC_SIGNAL() = default;

    enum DbcMuxStringFormat {
        MuxStringFormat_DbcFile,
        MuxStringFormat_UI
    };
    QString name;
    int startBit = 1;
    int signalSize = 1;
    bool intelByteOrder = false; //true is obviously little endian. False is big endian

    bool isMultiplexor = false;
    bool isMultiplexed = false;
    void addMultiplexRange(int min, int max);
    bool hasExtendedMultiplexing = false;
    QList<DBC_SIGNAL *> multiplexedChildren;
    DBC_SIGNAL *multiplexParent = nullptr;
    QString multiplexDbcString(DbcMuxStringFormat fmt = MuxStringFormat_DbcFile) const;
    void copyMultiplexValuesFromSignal(const DBC_SIGNAL &signal);
    bool parseDbcMultiplexUiString(const QString &multiplexes, QString &errorString);
    bool multiplexesIdenticalToSignal(DBC_SIGNAL *other) const;

    DBC_SIG_VAL_TYPE valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
    double factor = 1.0;
    double bias = 0;
    double min = 0;
    double max = 1;
    DBC_NODE *receiver = nullptr; //it is fast to have a pointer but dangerous... Make sure to walk the whole tree and delete everything so nobody has stale references.
    DBC_MESSAGE *parentMessage = nullptr;
    QString unitName;
    QString comment;
    QVariant cachedValue;
    QList<DBC_ATTRIBUTE_VALUE> attributes;
    QList<DBC_VAL_ENUM_ENTRY> valList;
    DBC_SIGNAL *self;

    bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true, bool outputUnit = true);
    bool processAsInt(const CANFrame &frame, int32_t &outValue);
    bool processAsDouble(const CANFrame &frame, double &outValue);
    bool getValueString(int64_t intVal, QString &outString);
    QString makePrettyOutput(double floatVal, int64_t intVal, bool outputName = true, bool isInteger = false, bool outputUnit = true);
    QString processSignalTree(const CANFrame &frame);
    DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
    DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);
    bool isSignalInMessage(const CANFrame &frame);
    bool isValueMatchingMultiplex(int val) const;
    int getSimpleMultiplexValue();


    friend bool operator<(const DBC_SIGNAL& l, const DBC_SIGNAL& r)
    {
        return (l.name.toLower() < r.name.toLower());
    }
private:
    QList<QPair<int, int>> multiplexLowAndHighValues;
};

class DBCSignalHandler; //forward declaration to keep from having to include dbchandler.h in this file and thus create a loop

class DBC_MESSAGE
{
public:
    DBC_MESSAGE();

    uint32_t ID;
    bool extendedID;
    QString name;
    QString comment;
    unsigned int len;
    DBC_NODE *sender;
    QColor bgColor;
    QColor fgColor;
    QList<DBC_ATTRIBUTE_VALUE> attributes;
    DBCSignalHandler *sigHandler;
    DBC_SIGNAL* multiplexorSignal;

    DBC_ATTRIBUTE_VALUE *findAttrValByName(QString name);
    DBC_ATTRIBUTE_VALUE *findAttrValByIdx(int idx);

    friend bool operator<(const DBC_MESSAGE& l, const DBC_MESSAGE& r)
    {
        return (l.name.toLower() < r.name.toLower());
    }
};


#endif // DBC_CLASSES_H