File: varicode.h

package info (click to toggle)
js8call 2.2.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 22,416 kB
  • sloc: cpp: 563,285; f90: 9,265; ansic: 937; python: 132; sh: 93; makefile: 6
file content (221 lines) | stat: -rw-r--r-- 7,919 bytes parent folder | download | duplicates (3)
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#ifndef VARICODE_H
#define VARICODE_H

/**
 * (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
 **/

#include <QBitArray>
#include <QRegularExpression>
#include <QRegExp>
#include <QString>
#include <QVector>
#include <QThread>


class Varicode
{
public:
    // extra information out of buildMessageFrames
    struct MessageInfo {
        QString dirTo;
        QString dirCmd;
        QString dirNum;
    };

    // submode types
    enum SubmodeType {
        JS8CallNormal    = 0,
        JS8CallFast      = 1,
        JS8CallTurbo     = 2,
        JS8CallSlow      = 4,
        JS8CallUltra     = 8
    };

    // frame type transmitted via itype and decoded by the ft8 decoded
    enum TransmissionType {
        JS8Call          = 0, // [000] <- any other frame of the message
        JS8CallFirst     = 1, // [001] <- the first frame of a message
        JS8CallLast      = 2, // [010] <- the last frame of a message
        JS8CallData      = 4, // [100] <- flagged frame (no frame type header)
    };

    /*

    000 = heartbeat
    001 = compound
    010 = compound directed
    011 = directed
    1XX = data, with the X lsb bits dropped
    */
    enum FrameType {
        FrameUnknown          = 255, // [11111111] <- only used as a sentinel
        FrameHeartbeat        = 0,   // [000]
        FrameCompound         = 1,   // [001]
        FrameCompoundDirected = 2,   // [010]
        FrameDirected         = 3,   // [011]
        FrameData             = 4,   // [10X] // but this only encodes the first 2 msb bits and drops the lsb
        FrameDataCompressed   = 6,   // [11X] // but this only encodes the first 2 msb bits and drops the lsb
    };

    static const quint8 FrameTypeMax = 6;

    static QString frameTypeString(quint8 type) {
        const char* FrameTypeStrings[] = {
            "FrameHeartbeat",
            "FrameCompound",
            "FrameCompoundDirected",
            "FrameDirected",
            "FrameData",
            "FrameUnknown", // 5
            "FrameDataCompressed",
        };

        if(type > FrameTypeMax){
            return "FrameUnknown";
        }
        return FrameTypeStrings[type];
    }

    //Varicode();

    static QString extendedChars();

    static QString escape(const QString &text);
    static QString unescape(const QString &text);

    static QString rstrip(const QString& str);
    static QString lstrip(const QString& str);

    static QMap<QString, QString> defaultHuffTable();
    static QString cqString(int number);
    static QString hbString(int number);
    static bool startsWithCQ(QString text);
    static bool startsWithHB(QString text);
    static QString formatSNR(int snr);
    static QString formatPWR(int dbm);

    static QString checksum16(QString const &input);
    static bool checksum16Valid(QString const &checksum, QString const &input);

    static QString checksum32(QString const &input);
    static bool checksum32Valid(QString const &checksum, QString const &input);

    static QStringList parseCallsigns(QString const &input);
    static QStringList parseGrids(QString const &input);

    static QList<QPair<int, QVector<bool>>> huffEncode(const QMap<QString, QString> &huff, QString const& text);
    static QString huffDecode(const QMap<QString, QString> &huff, QVector<bool> const& bitvec);
    static QSet<QString> huffValidChars(const QMap<QString, QString> &huff);

    static QVector<bool> bytesToBits(char * bitvec, int n);
    static QVector<bool> strToBits(QString const& bitvec);
    static QString bitsToStr(QVector<bool> const& bitvec);

    static QVector<bool> intToBits(quint64 value, int expected=0);
    static quint64 bitsToInt(QVector<bool> const value);
    static quint64 bitsToInt(QVector<bool>::ConstIterator start, int n);
    static QVector<bool> bitsListToBits(QList<QVector<bool>> &list);

    static quint8 unpack5bits(QString const& value);
    static QString pack5bits(quint8 packed);

    static quint8 unpack6bits(QString const& value);
    static QString pack6bits(quint8 packed);

    static quint16 unpack16bits(QString const& value);
    static QString pack16bits(quint16 packed);

    static quint32 unpack32bits(QString const& value);
    static QString pack32bits(quint32 packed);

    static quint64 unpack64bits(QString const& value);
    static QString pack64bits(quint64 packed);

    static quint64 unpack72bits(QString const& value, quint8 *pRem);
    static QString pack72bits(quint64 value, quint8 rem);

    static quint32 packAlphaNumeric22(QString const& value, bool isFlag);
    static QString unpackAlphaNumeric22(quint32 packed, bool *isFlag);

    static quint64 packAlphaNumeric50(QString const& value);
    static QString unpackAlphaNumeric50(quint64 packed);

    static quint32 packCallsign(QString const& value, bool *pPortable);
    static QString unpackCallsign(quint32 value, bool portable);

    static QString deg2grid(float dlong, float dlat);
    static QPair<float, float> grid2deg(QString const &grid);
    static quint16 packGrid(QString const& value);
    static QString unpackGrid(quint16 value);

    static quint8 packNum(QString const &num, bool *ok);
    static quint8 packPwr(QString const &pwr, bool *ok);
    static quint8 packCmd(quint8 cmd, quint8 num, bool *pPackedNum);
    static quint8 unpackCmd(quint8 value, quint8 *pNum);

    static bool isSNRCommand(const QString &cmd);
    static bool isCommandAllowed(const QString &cmd);
    static bool isCommandBuffered(const QString &cmd);
    static int isCommandChecksumed(const QString &cmd);
    static bool isCommandAutoreply(const QString &cmd);
    static bool isValidCallsign(const QString &callsign, bool *pIsCompound);
    static bool isCompoundCallsign(const QString &callsign);
    static bool isGroupAllowed(const QString &group);

    static QString packHeartbeatMessage(QString const &text, QString const&callsign, int *n);
    static QStringList unpackHeartbeatMessage(const QString &text, quint8 *pType, bool *isAlt, quint8 *pBits3);

    static QString packCompoundMessage(QString const &text, int *n);
    static QStringList unpackCompoundMessage(const QString &text, quint8 *pType, quint8 *pBits3);

    static QString packCompoundFrame(const QString &callsign, quint8 type, quint16 num, quint8 bits3);
    static QStringList unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum, quint8 *pBits3);

    static QString packDirectedMessage(QString const& text, QString const& mycall, QString *pTo, bool *pToCompound, QString * pCmd, QString *pNum, int *n);
    static QStringList unpackDirectedMessage(QString const& text, quint8 *pType);

    static QString packDataMessage(QString const& text, int *n);
    static QString unpackDataMessage(QString const& text);

    static QString packFastDataMessage(QString const& text, int *n);
    static QString unpackFastDataMessage(QString const& text);

    static QList<QPair<QString, int>> buildMessageFrames(QString const& mycall,
        QString const& mygrid,
        QString const& selectedCall,
        QString const& text,
        bool forceIdentify,
        bool forceData,
        int submode,
        MessageInfo *pInfo=nullptr);
};


class BuildMessageFramesThread : public QThread
{
    Q_OBJECT
public:
    BuildMessageFramesThread(QString const& mycall,
                             QString const& mygrid,
                             QString const& selectedCall,
                             QString const& text,
                             bool forceIdentify,
                             bool forceData,
                             int submode,
                             QObject *parent=nullptr);
    void run() override;
signals:
    void resultReady(QString, int);

private:
    QString m_mycall;
    QString m_mygrid;
    QString m_selectedCall;
    QString m_text;
    bool m_forceIdentify;
    bool m_forceData;
    int m_submode;
};

#endif // VARICODE_H