js8call/JS8_Main/Varicode.h
Chris-AC9KH 1ab08249b1 remove MainWindow class from mainwindow.cpp and replace it with UI_Constructor class
rename remaining files that didn't match their class definitions
relocate the explicit UI_Constructor member function to JS8_MainWindow
relocate the processBufferedActivity member function to JS8_MainWindow
format affected files with LLVM clang-format

Set default APRS inbound relay to off
Fix layout of General->Networking & Autoreply tab in Settings
2026-01-18 19:19:15 -06:00

222 lines
8.1 KiB
C++

#ifndef VARICODE_H
#define VARICODE_H
/**
* (C) 2018 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
**/
#include <QBitArray>
#include <QRegularExpression>
#include <QString>
#include <QThread>
#include <QVector>
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 SubmodeType intToSubmode(int sm);
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