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
|