Refactoring directed frame packing
This commit is contained in:
parent
f7a941406c
commit
07a29c7f1d
159
varicode.cpp
159
varicode.cpp
@ -46,6 +46,9 @@ QMap<QString, int> directed_cmds = {
|
|||||||
{"|", 4 }, // relay message
|
{"|", 4 }, // relay message
|
||||||
{"!", 5 }, // alert message
|
{"!", 5 }, // alert message
|
||||||
|
|
||||||
|
// special responses
|
||||||
|
// {"/", 10 }, // compound callsign
|
||||||
|
|
||||||
// directed responses
|
// directed responses
|
||||||
{" ACK", 23 }, // acknowledge
|
{" ACK", 23 }, // acknowledge
|
||||||
{" PWR", 24 }, // power level
|
{" PWR", 24 }, // power level
|
||||||
@ -58,7 +61,7 @@ QMap<QString, int> directed_cmds = {
|
|||||||
{" ", 31 }, // send freetext
|
{" ", 31 }, // send freetext
|
||||||
};
|
};
|
||||||
|
|
||||||
QSet<int> allowed_cmds = {0, 1, 2, /*3,*/ 4, /*5,*/ 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
QSet<int> allowed_cmds = {0, 1, 2, /*3,*/ 4, /*5,*/ 10, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||||
|
|
||||||
QRegularExpression directed_re("^"
|
QRegularExpression directed_re("^"
|
||||||
"(?<to>[A-Z0-9/]+)"
|
"(?<to>[A-Z0-9/]+)"
|
||||||
@ -115,6 +118,8 @@ QMap<QChar, QString> huff = {
|
|||||||
{'-' , "110101101110" }, // 5
|
{'-' , "110101101110" }, // 5
|
||||||
{'/' , "110101101111" }, // 5
|
{'/' , "110101101111" }, // 5
|
||||||
{'\x04' , "110101100010" }, // 1 <- eot
|
{'\x04' , "110101100010" }, // 1 <- eot
|
||||||
|
|
||||||
|
// A-Z 0-9 Space . ! ? ^ : + - /
|
||||||
};
|
};
|
||||||
|
|
||||||
QChar huffeot = '\x04';
|
QChar huffeot = '\x04';
|
||||||
@ -122,7 +127,8 @@ QChar huffeot = '\x04';
|
|||||||
quint32 nbasecall = 37 * 36 * 10 * 27 * 27 * 27;
|
quint32 nbasecall = 37 * 36 * 10 * 27 * 27 * 27;
|
||||||
|
|
||||||
QMap<QString, quint32> basecalls = {
|
QMap<QString, quint32> basecalls = {
|
||||||
{ "CQCQCQ", nbasecall + 1 },
|
{ "<....>", nbasecall + 1 }, // incomplete callsign
|
||||||
|
{ "CQCQCQ", nbasecall + 2 },
|
||||||
{ "ALLCALL", nbasecall + 3 },
|
{ "ALLCALL", nbasecall + 3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -657,82 +663,92 @@ bool Varicode::isCommandAllowed(const QString &cmd){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: jsherer - rename to tryPackDirectedMessage, and break apart the actual packing code into a separate function
|
|
||||||
QString Varicode::packDirectedMessage(const QString &text, const QString &callsign, int *n){
|
QString Varicode::packDirectedMessage(const QString &text, const QString &callsign, int *n){
|
||||||
QString frame;
|
QString frame;
|
||||||
|
|
||||||
auto match = directed_re.match(text);
|
auto match = directed_re.match(text);
|
||||||
if(match.hasMatch()){
|
if(!match.hasMatch()){
|
||||||
QString from = callsign;
|
if(n) *n = 0;
|
||||||
QString to = match.captured("to");
|
|
||||||
QString cmd = match.captured("cmd");
|
|
||||||
QString num = match.captured("num").trimmed();
|
|
||||||
QString pwr = match.captured("pwr").trimmed();
|
|
||||||
|
|
||||||
int inum = -31;
|
|
||||||
bool hasnum = false;
|
|
||||||
if(!num.isEmpty()){
|
|
||||||
inum = qMax(-30, qMin(num.toInt(&hasnum, 10), 30));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we are packing a PWR command, pack pwr into dbm
|
|
||||||
int ipwr = -31;
|
|
||||||
if(!pwr.isEmpty() && cmd.trimmed() == "PWR"){
|
|
||||||
int factor = 1000;
|
|
||||||
if(pwr.endsWith("KW")){
|
|
||||||
factor = 1000000;
|
|
||||||
}
|
|
||||||
else if(pwr.endsWith("MW")){
|
|
||||||
factor = 1;
|
|
||||||
}
|
|
||||||
ipwr = pwr.replace(QRegExp("[KM]?W"), "").toInt() * factor;
|
|
||||||
inum = mwattsToDbm(ipwr) - 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(to == callsign){
|
|
||||||
*n = 0;
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validToCallsign = basecalls.contains(to) || QRegularExpression(callsign_pattern2).match(to).hasMatch();
|
|
||||||
if(!validToCallsign || !Varicode::isCommandAllowed(cmd)){
|
|
||||||
*n = 0;
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: jsherer - we don't need this CRC... the FT8 msg already has a 12 bit CRC...
|
|
||||||
//auto fromBytes = from.toLocal8Bit();
|
|
||||||
//auto fromCRC = CRC::Calculate(fromBytes.data(), fromBytes.length(), CRC::CRC_5_ITU());
|
|
||||||
|
|
||||||
quint8 packed_is_data = 0;
|
|
||||||
quint8 packed_flag = inum < 0 ? 1 : 0;
|
|
||||||
quint32 packed_from = Varicode::packCallsign(from);
|
|
||||||
quint32 packed_to = Varicode::packCallsign(to);
|
|
||||||
|
|
||||||
if(packed_from == 0 || packed_to == 0){
|
|
||||||
*n = 0;
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint8 packed_cmd = directed_cmds[cmd];
|
|
||||||
quint8 packed_extra = qAbs(inum);
|
|
||||||
|
|
||||||
// [1][2][28][28][5],[5] = 69
|
|
||||||
auto bits = (
|
|
||||||
Varicode::intToBits(packed_is_data, 1) +
|
|
||||||
Varicode::intToBits(packed_flag, 2) +
|
|
||||||
Varicode::intToBits(packed_from, 28) +
|
|
||||||
Varicode::intToBits(packed_to, 28) +
|
|
||||||
Varicode::intToBits(packed_cmd & 31, 5)
|
|
||||||
);
|
|
||||||
frame = Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_extra & 31);
|
|
||||||
*n = match.captured(0).length();
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString from = callsign;
|
||||||
|
QString to = match.captured("to");
|
||||||
|
QString cmd = match.captured("cmd");
|
||||||
|
QString num = match.captured("num").trimmed();
|
||||||
|
QString pwr = match.captured("pwr").trimmed();
|
||||||
|
|
||||||
|
// validate callsign
|
||||||
|
bool validToCallsign = to != callsign && (basecalls.contains(to) || QRegularExpression(callsign_pattern2).match(to).hasMatch());
|
||||||
|
if(!validToCallsign){
|
||||||
|
if(n) *n = 0;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate command
|
||||||
|
if(!Varicode::isCommandAllowed(cmd)){
|
||||||
|
if(n) *n = 0;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
// packing general number...
|
||||||
|
int inum = -31;
|
||||||
|
bool hasnum = false;
|
||||||
|
if(!num.isEmpty()){
|
||||||
|
inum = qMax(-30, qMin(num.toInt(&hasnum, 10), 30));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we are packing a PWR command, pack pwr as dbm
|
||||||
|
int ipwr = -31;
|
||||||
|
if(!pwr.isEmpty() && cmd.trimmed() == "PWR"){
|
||||||
|
int factor = 1000;
|
||||||
|
if(pwr.endsWith("KW")){
|
||||||
|
factor = 1000000;
|
||||||
|
}
|
||||||
|
else if(pwr.endsWith("MW")){
|
||||||
|
factor = 1;
|
||||||
|
}
|
||||||
|
ipwr = pwr.replace(QRegExp("[KM]?W"), "").toInt() * factor;
|
||||||
|
inum = mwattsToDbm(ipwr) - 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = Varicode::packDirectedFrame(from, to, cmd, inum);
|
||||||
|
if(frame.isEmpty()){
|
||||||
|
if(n) *n = 0;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n) *n = match.captured(0).length();
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Varicode::packDirectedFrame(const QString &from, const QString &to, const QString &cmd, int inum){
|
||||||
|
QString frame;
|
||||||
|
|
||||||
|
quint8 packed_is_data = 0;
|
||||||
|
quint8 packed_flag = inum < 0 ? 1 : 0;
|
||||||
|
quint32 packed_from = Varicode::packCallsign(from);
|
||||||
|
quint32 packed_to = Varicode::packCallsign(to);
|
||||||
|
|
||||||
|
if(packed_from == 0 || packed_to == 0){
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 packed_cmd = directed_cmds[cmd];
|
||||||
|
quint8 packed_extra = qAbs(inum);
|
||||||
|
|
||||||
|
// [1][2][28][28][5],[5] = 69
|
||||||
|
auto bits = (
|
||||||
|
Varicode::intToBits(packed_is_data, 1) +
|
||||||
|
Varicode::intToBits(packed_flag, 2) +
|
||||||
|
Varicode::intToBits(packed_from, 28) +
|
||||||
|
Varicode::intToBits(packed_to, 28) +
|
||||||
|
Varicode::intToBits(packed_cmd & 31, 5)
|
||||||
|
);
|
||||||
|
|
||||||
|
return Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_extra & 31);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList Varicode::unpackDirectedMessage(const QString &text){
|
QStringList Varicode::unpackDirectedMessage(const QString &text){
|
||||||
QStringList unpacked;
|
QStringList unpacked;
|
||||||
|
|
||||||
@ -755,13 +771,6 @@ QStringList Varicode::unpackDirectedMessage(const QString &text){
|
|||||||
|
|
||||||
QString from = Varicode::unpackCallsign(packed_from).trimmed();
|
QString from = Varicode::unpackCallsign(packed_from).trimmed();
|
||||||
|
|
||||||
// TODO: jsherer - we don't need this CRC... the FT8 msg already has a 12 bit CRC...
|
|
||||||
//auto fromBytes = from.toLocal8Bit();
|
|
||||||
//auto fromCRC = CRC::Calculate(fromBytes.data(), fromBytes.length(), CRC::CRC_5_ITU());
|
|
||||||
//if(fromCRC != extra){
|
|
||||||
// return unpacked;
|
|
||||||
//}
|
|
||||||
|
|
||||||
unpacked.append(from);
|
unpacked.append(from);
|
||||||
unpacked.append(Varicode::unpackCallsign(packed_to).trimmed());
|
unpacked.append(Varicode::unpackCallsign(packed_to).trimmed());
|
||||||
unpacked.append(directed_cmds.key(packed_cmd & 31));
|
unpacked.append(directed_cmds.key(packed_cmd & 31));
|
||||||
|
@ -74,6 +74,7 @@ public:
|
|||||||
|
|
||||||
static bool isCommandAllowed(const QString &cmd);
|
static bool isCommandAllowed(const QString &cmd);
|
||||||
static QString packDirectedMessage(QString const& text, QString const& callsign, int *n);
|
static QString packDirectedMessage(QString const& text, QString const& callsign, int *n);
|
||||||
|
static QString packDirectedFrame(const QString &from, const QString &to, const QString &cmd, int inum);
|
||||||
static QStringList unpackDirectedMessage(QString const& text);
|
static QStringList unpackDirectedMessage(QString const& text);
|
||||||
|
|
||||||
static QString packDataMessage(QString const& text, int *n);
|
static QString packDataMessage(QString const& text, int *n);
|
||||||
|
Loading…
Reference in New Issue
Block a user