Starting compound call refactoring

This commit is contained in:
Jordan Sherer 2018-07-29 10:39:58 -04:00
parent 62899069bf
commit 565f4d9321
5 changed files with 110 additions and 47 deletions

View File

@ -76,7 +76,7 @@ bool DecodedText::tryUnpack(){
bool unpacked = false; bool unpacked = false;
if(!unpacked){ if(!unpacked){
unpacked = tryUnpackCompound(); unpacked = tryUnpackBeacon();
} }
if(!unpacked){ if(!unpacked){
@ -90,7 +90,7 @@ bool DecodedText::tryUnpack(){
return unpacked; return unpacked;
} }
bool DecodedText::tryUnpackCompound(){ bool DecodedText::tryUnpackBeacon(){
QString m = message().trimmed(); QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces. // directed calls will always be 12+ chars and contain no spaces.
@ -98,14 +98,23 @@ bool DecodedText::tryUnpackCompound(){
return false; return false;
} }
QStringList parts = Varicode::unpackCompoundMessage(m, nullptr); bool isBCN = false;
QStringList parts = Varicode::unpackBeaconMessage(m, &isBCN);
if(parts.isEmpty() || parts.length() < 2){ if(parts.isEmpty() || parts.length() < 2){
return false; return false;
} }
compound_ = QString("%1/%2").arg(parts.at(0), parts.at(1)); auto extra = parts.at(2);
compound_ = QStringList{ parts.at(0), parts.at(1) }.join("/");
if(isBCN){
message_ = QString("%1: BCN %2 ").arg(compound_).arg(extra);
} else {
message_ = QString("%1: ").arg(compound_); message_ = QString("%1: ").arg(compound_);
}
return true; return true;
} }

View File

@ -34,7 +34,7 @@ public:
explicit DecodedText (QString const& ft8callmessage); explicit DecodedText (QString const& ft8callmessage);
bool tryUnpack(); bool tryUnpack();
bool tryUnpackCompound(); bool tryUnpackBeacon();
bool tryUnpackDirected(); bool tryUnpackDirected();
bool tryUnpackData(); bool tryUnpackData();

View File

@ -3454,7 +3454,7 @@ void MainWindow::readFromStdout() //readFromStdout
CallDetail cd; CallDetail cd;
cd.call = compoundCall; cd.call = compoundCall;
cd.grid = ""; cd.grid = ""; // compound calls via beacons contain grid...
cd.snr = decodedtext.snr(); cd.snr = decodedtext.snr();
cd.freq = decodedtext.frequencyOffset(); cd.freq = decodedtext.frequencyOffset();
cd.utcTimestamp = QDateTime::currentDateTimeUtc(); cd.utcTimestamp = QDateTime::currentDateTimeUtc();
@ -5776,6 +5776,7 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
// prepare compound // prepare compound
bool compoundSent = false; bool compoundSent = false;
bool compound = Radio::is_compound_callsign(m_config.my_callsign()); bool compound = Radio::is_compound_callsign(m_config.my_callsign());
QString mygrid = m_config.my_grid();
QString mycall = m_config.my_callsign(); QString mycall = m_config.my_callsign();
QString basecall = Radio::base_callsign(m_config.my_callsign()); QString basecall = Radio::base_callsign(m_config.my_callsign());
QString fix = QString(m_config.my_callsign()).replace(basecall, ""); QString fix = QString(m_config.my_callsign()).replace(basecall, "");
@ -5787,15 +5788,27 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
// once we find a directed call, data encode the rest of the line. // once we find a directed call, data encode the rest of the line.
bool hasDirected = false; bool hasDirected = false;
// remove our callsign from the start of the line...
if(line.startsWith(mycall + ":")){
line = lstrip(line.mid(mycall.length() + 1));
}
if(line.startsWith(basecall + ":")){
line = lstrip(line.mid(basecall.length() + 1));
}
while(line.size() > 0){ while(line.size() > 0){
QString frame; QString frame;
bool useStd = false; bool useStd = false;
bool useBcn = false;
bool useDir = false; bool useDir = false;
bool useDat = false; bool useDat = false;
bool isFree = false; bool isFree = false;
QString stdFrame = parseFT8Message(line, &isFree); QString stdFrame = parseFT8Message(line, &isFree);
int l = 0;
QString bcnFrame = Varicode::packBeaconMessage(line, mycall, &l);
int n = 0; int n = 0;
QString dirCmd; QString dirCmd;
QString dirFrame = Varicode::packDirectedMessage(line, basecall, &dirCmd, &n); QString dirFrame = Varicode::packDirectedMessage(line, basecall, &dirCmd, &n);
@ -5807,12 +5820,21 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
// if this parses to a standard FT8 free text message // if this parses to a standard FT8 free text message
// but it can be parsed as a directed message, then we // but it can be parsed as a directed message, then we
// should send the directed version // should send the directed version. if we've already sent
if(isFree && !hasDirected && n > 0){ // a directed message, we won't send any more but instead
// send it as a data message
if(isFree && !hasDirected && l > 0){
useBcn = true;
hasDirected = false;
frame = bcnFrame;
}
else if(isFree && !hasDirected && n > 0){
useDir = true; useDir = true;
hasDirected = true; hasDirected = true;
frame = dirFrame; frame = dirFrame;
} else if ((isFree || hasDirected) && m > 0) { }
else if ((isFree || hasDirected) && m > 0) {
useDat = true; useDat = true;
frame = datFrame; frame = datFrame;
if(!datLineOut.isEmpty()){ if(!datLineOut.isEmpty()){
@ -5840,13 +5862,19 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
line = line.mid(frame.length()).trimmed(); line = line.mid(frame.length()).trimmed();
} }
if(useBcn){
frames.append(frame);
lines.append(QString("%1: ").arg(mycall) + line.left(l) + " ");
line = line.mid(l);
}
if(useDir){ if(useDir){
if(compound && !compoundSent){ if(compound && !compoundSent){
QString compoundFrame = Varicode::packCompoundMessage(basecall, fix, prefix, 0); QString compoundMessage = QString("DE %1").arg(mygrid);
if(!compoundFrame.isEmpty()){ QString beaconFrame = Varicode::packBeaconMessage(compoundMessage, mycall, nullptr);
frames.append(compoundFrame); if(!beaconFrame.isEmpty()){
frames.append(beaconFrame);
lines.append(QString("%1: ").arg(mycall)); lines.append(QString("%1: ").arg(mycall));
compoundSent = true;
} }
} }
@ -5881,7 +5909,7 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
#if 1 #if 1
qDebug() << "parsed frames:"; qDebug() << "parsed frames:";
foreach(auto frame, frames){ foreach(auto frame, frames){
qDebug() << "->" << frame << Varicode::unpackDataMessage(frame) << Varicode::unpackDirectedMessage(frame) << Varicode::unpackCompoundMessage(frame, nullptr); qDebug() << "->" << frame << Varicode::unpackDataMessage(frame) << Varicode::unpackDirectedMessage(frame) << Varicode::unpackCompoundFrame(frame, nullptr) << Varicode::unpackBeaconMessage(frame, nullptr);
} }
qDebug() << "lines:"; qDebug() << "lines:";
@ -6108,8 +6136,11 @@ void MainWindow::prepareBacon(){
beacon = QString("DE %1").arg(call).arg(grid); beacon = QString("DE %1").arg(call).arg(grid);
} }
// FT8 Style
lines.append(beacon); lines.append(beacon);
lines.append(beacon);
// FT8Call Style
lines.append(QString("%1: BCN %2").arg(call).arg(grid));
#if 0 #if 0
if(!m_callActivity.isEmpty()){ if(!m_callActivity.isEmpty()){
@ -8793,6 +8824,9 @@ void MainWindow::displayActivity(bool force){
} }
} }
// Grouped Compound Activity
// TODO: jsherer - group compound callsign and directed commands together.
// Buffered Activity // Buffered Activity
foreach(auto freq, m_messageBuffer.keys()){ foreach(auto freq, m_messageBuffer.keys()){
auto buffer = m_messageBuffer[freq]; auto buffer = m_messageBuffer[freq];
@ -8866,7 +8900,7 @@ void MainWindow::displayActivity(bool force){
// QUERIED SNR // QUERIED SNR
if(d.cmd == "?"){ if(d.cmd == "?"){
reply = QString("%1 SNR %2").arg(Radio::base_callsign(d.from)).arg(Varicode::formatSNR(d.snr)); reply = QString("%1 SNR %2").arg(d.from).arg(Varicode::formatSNR(d.snr));
} }
// QUERIED ACK // QUERIED ACK
//else if(d.cmd == "#"){ //else if(d.cmd == "#"){
@ -8874,7 +8908,7 @@ void MainWindow::displayActivity(bool force){
//} //}
// QUERIED PWR // QUERIED PWR
else if(d.cmd == "%" && !isAllCall && m_config.my_dBm() >= 0){ else if(d.cmd == "%" && !isAllCall && m_config.my_dBm() >= 0){
reply = QString("%1 PWR %2").arg(Radio::base_callsign(d.from)).arg(Varicode::formatPWR(m_config.my_dBm())); reply = QString("%1 PWR %2").arg(d.from).arg(Varicode::formatPWR(m_config.my_dBm()));
} }
// QUERIED QTH // QUERIED QTH
else if(d.cmd == "@" && !isAllCall){ else if(d.cmd == "@" && !isAllCall){
@ -8887,11 +8921,11 @@ void MainWindow::displayActivity(bool force){
qth = grid; qth = grid;
} }
reply = QString("%1 %2").arg(Radio::base_callsign(d.from)).arg(qth); reply = QString("%1 %2").arg(d.from).arg(qth);
} }
// QUERIED STATION MESSAGE // QUERIED STATION MESSAGE
else if(d.cmd == "&" && !isAllCall){ else if(d.cmd == "&" && !isAllCall){
reply = QString("%1 %2").arg(Radio::base_callsign(d.from)).arg(m_config.my_station()); reply = QString("%1 %2").arg(d.from).arg(m_config.my_station());
} }
// QUERIED STATIONS HEARD // QUERIED STATIONS HEARD
else if(d.cmd == "$" && !isAllCall){ else if(d.cmd == "$" && !isAllCall){
@ -8909,12 +8943,9 @@ void MainWindow::displayActivity(bool force){
if(i >= maxStations){ if(i >= maxStations){
break; break;
} }
if(Radio::base_callsign(call) == Radio::base_callsign(m_config.my_callsign())){
continue;
}
auto d = m_callActivity[call]; auto d = m_callActivity[call];
lines.append(QString("%1 SNR %2").arg(Radio::base_callsign(call)).arg(Varicode::formatSNR(d.snr))); lines.append(QString("%1 SNR %2").arg(d.call).arg(Varicode::formatSNR(d.snr)));
i++; i++;
} }
reply = lines.join('\n'); reply = lines.join('\n');

View File

@ -52,6 +52,7 @@ QMap<QString, int> directed_cmds = {
// {"/", 9 }, // unused? (can we even use stroke?) // {"/", 9 }, // unused? (can we even use stroke?)
// directed responses // directed responses
{" BCN", 22 }, // beacon
{" ACK", 23 }, // acknowledged {" ACK", 23 }, // acknowledged
{" PWR", 24 }, // power level {" PWR", 24 }, // power level
{" SNR", 25 }, // seen a station at the provided snr {" SNR", 25 }, // seen a station at the provided snr
@ -805,11 +806,26 @@ bool Varicode::isCommandBuffered(const QString &cmd){
return directed_cmds.contains(cmd) && buffered_cmds.contains(directed_cmds[cmd]); return directed_cmds.contains(cmd) && buffered_cmds.contains(directed_cmds[cmd]);
} }
QString Varicode::packBeaconMessage(QString const &callsign, QString const &extra, bool isCQ){ QString Varicode::packBeaconMessage(QString const &text, const QString &callsign, int *n){
QString frame; QString frame;
auto parsedText = QRegularExpression(R"(^(?<type>BCN|DE)\s(?<grid>[A-Z]{2}[0-9]{2})\b)").match(text);
if(!parsedText.hasMatch()){
if(n) *n = 0;
return frame;
}
auto extra = parsedText.captured("grid");
if(extra.isEmpty()){
if(n) *n = 0;
return frame;
}
auto isBCN = parsedText.captured("type") == "BCN";
auto parsedCall = QRegularExpression(compound_callsign_pattern).match(callsign); auto parsedCall = QRegularExpression(compound_callsign_pattern).match(callsign);
if(!parsedCall.hasMatch()){ if(!parsedCall.hasMatch()){
if(n) *n = 0;
return frame; return frame;
} }
@ -830,26 +846,33 @@ QString Varicode::packBeaconMessage(QString const &callsign, QString const &extr
packed_extra = Varicode::packGrid(extra); packed_extra = Varicode::packGrid(extra);
} }
if(isCQ){ if(isBCN){
packed_extra |= (1<<15); packed_extra |= (1<<15);
} }
return packCompoundMessage(base, fix, isPrefix, packed_extra); frame = packCompoundFrame(base, fix, isPrefix, packed_extra);
if(frame.isEmpty()){
if(n) *n = 0;
return frame;
} }
QStringList Varicode::unpackBeaconMessage(const QString &text, bool * isCQ){ if(n) *n = parsedText.captured(0).length();
return frame;
}
QStringList Varicode::unpackBeaconMessage(const QString &text, bool * isBCN){
quint16 num = 0; quint16 num = 0;
QStringList unpacked = unpackCompoundMessage(text, &num); QStringList unpacked = unpackCompoundFrame(text, &num);
if(isCQ) *isCQ = (num & (1<<15)); if(isBCN) *isBCN = (num & (1<<15));
unpacked.append(Varicode::unpackGrid(num & ((1<<15)-1))); unpacked.append(Varicode::unpackGrid(num & ((1<<15)-1)));
return unpacked; return unpacked;
} }
QString Varicode::packCompoundMessage(const QString &baseCallsign, const QString &fix, bool isPrefix, quint16 num){ QString Varicode::packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint16 num){
QString frame; QString frame;
quint8 packed_is_data = 0; quint8 packed_is_data = 0;
@ -881,7 +904,7 @@ QString Varicode::packCompoundMessage(const QString &baseCallsign, const QString
return Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_5 % 32); return Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_5 % 32);
} }
QStringList Varicode::unpackCompoundMessage(const QString &text, quint16 *pNum){ QStringList Varicode::unpackCompoundFrame(const QString &text, quint16 *pNum){
QStringList unpacked; QStringList unpacked;
if(text.length() < 13 || text.contains(" ")){ if(text.length() < 13 || text.contains(" ")){

View File

@ -83,11 +83,11 @@ public:
static bool isCommandAllowed(const QString &cmd); static bool isCommandAllowed(const QString &cmd);
static bool isCommandBuffered(const QString &cmd); static bool isCommandBuffered(const QString &cmd);
static QString packBeaconMessage(QString const &callsign, QString const &extra, bool isCQ); static QString packBeaconMessage(QString const &text, QString const&callsign, int *n);
static QStringList unpackBeaconMessage(const QString &text, bool *isCQ); static QStringList unpackBeaconMessage(const QString &text, bool *isBCN);
static QString packCompoundMessage(const QString &baseCallsign, const QString &fix, bool isPrefix, quint16 num); static QString packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint16 num);
static QStringList unpackCompoundMessage(const QString &text, quint16 *pNum); static QStringList unpackCompoundFrame(const QString &text, quint16 *pNum);
static QString packDirectedMessage(QString const& text, QString const& callsign, QString * pCmd, int *n); static QString packDirectedMessage(QString const& text, QString const& callsign, QString * pCmd, int *n);
static QStringList unpackDirectedMessage(QString const& text); static QStringList unpackDirectedMessage(QString const& text);