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;
if(!unpacked){
unpacked = tryUnpackCompound();
unpacked = tryUnpackBeacon();
}
if(!unpacked){
@ -90,23 +90,32 @@ bool DecodedText::tryUnpack(){
return unpacked;
}
bool DecodedText::tryUnpackCompound(){
QString m = message().trimmed();
bool DecodedText::tryUnpackBeacon(){
QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
QStringList parts = Varicode::unpackCompoundMessage(m, nullptr);
bool isBCN = false;
QStringList parts = Varicode::unpackBeaconMessage(m, &isBCN);
if(parts.isEmpty() || parts.length() < 2){
return false;
}
if(parts.isEmpty() || parts.length() < 2){
return false;
}
compound_ = QString("%1/%2").arg(parts.at(0), parts.at(1));
message_ = QString("%1: ").arg(compound_);
return true;
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_);
}
return true;
}
bool DecodedText::tryUnpackDirected(){

View File

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

View File

@ -3454,7 +3454,7 @@ void MainWindow::readFromStdout() //readFromStdout
CallDetail cd;
cd.call = compoundCall;
cd.grid = "";
cd.grid = ""; // compound calls via beacons contain grid...
cd.snr = decodedtext.snr();
cd.freq = decodedtext.frequencyOffset();
cd.utcTimestamp = QDateTime::currentDateTimeUtc();
@ -5776,6 +5776,7 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
// prepare compound
bool compoundSent = false;
bool compound = Radio::is_compound_callsign(m_config.my_callsign());
QString mygrid = m_config.my_grid();
QString mycall = m_config.my_callsign();
QString basecall = Radio::base_callsign(m_config.my_callsign());
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.
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){
QString frame;
bool useStd = false;
bool useBcn = false;
bool useDir = false;
bool useDat = false;
bool isFree = false;
QString stdFrame = parseFT8Message(line, &isFree);
int l = 0;
QString bcnFrame = Varicode::packBeaconMessage(line, mycall, &l);
int n = 0;
QString dirCmd;
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
// but it can be parsed as a directed message, then we
// should send the directed version
if(isFree && !hasDirected && n > 0){
// should send the directed version. if we've already sent
// 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;
hasDirected = true;
frame = dirFrame;
} else if ((isFree || hasDirected) && m > 0) {
}
else if ((isFree || hasDirected) && m > 0) {
useDat = true;
frame = datFrame;
if(!datLineOut.isEmpty()){
@ -5840,14 +5862,20 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
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(compound && !compoundSent){
QString compoundFrame = Varicode::packCompoundMessage(basecall, fix, prefix, 0);
if(!compoundFrame.isEmpty()){
frames.append(compoundFrame);
lines.append(QString("%1: ").arg(mycall));
compoundSent = true;
}
QString compoundMessage = QString("DE %1").arg(mygrid);
QString beaconFrame = Varicode::packBeaconMessage(compoundMessage, mycall, nullptr);
if(!beaconFrame.isEmpty()){
frames.append(beaconFrame);
lines.append(QString("%1: ").arg(mycall));
}
}
frames.append(frame);
@ -5881,7 +5909,7 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
#if 1
qDebug() << "parsed 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:";
@ -6108,8 +6136,11 @@ void MainWindow::prepareBacon(){
beacon = QString("DE %1").arg(call).arg(grid);
}
// FT8 Style
lines.append(beacon);
lines.append(beacon);
// FT8Call Style
lines.append(QString("%1: BCN %2").arg(call).arg(grid));
#if 0
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
foreach(auto freq, m_messageBuffer.keys()){
auto buffer = m_messageBuffer[freq];
@ -8866,7 +8900,7 @@ void MainWindow::displayActivity(bool force){
// QUERIED SNR
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
//else if(d.cmd == "#"){
@ -8874,7 +8908,7 @@ void MainWindow::displayActivity(bool force){
//}
// QUERIED PWR
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
else if(d.cmd == "@" && !isAllCall){
@ -8887,11 +8921,11 @@ void MainWindow::displayActivity(bool force){
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
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
else if(d.cmd == "$" && !isAllCall){
@ -8909,12 +8943,9 @@ void MainWindow::displayActivity(bool force){
if(i >= maxStations){
break;
}
if(Radio::base_callsign(call) == Radio::base_callsign(m_config.my_callsign())){
continue;
}
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++;
}
reply = lines.join('\n');

View File

@ -52,6 +52,7 @@ QMap<QString, int> directed_cmds = {
// {"/", 9 }, // unused? (can we even use stroke?)
// directed responses
{" BCN", 22 }, // beacon
{" ACK", 23 }, // acknowledged
{" PWR", 24 }, // power level
{" 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]);
}
QString Varicode::packBeaconMessage(QString const &callsign, QString const &extra, bool isCQ){
QString Varicode::packBeaconMessage(QString const &text, const QString &callsign, int *n){
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);
if(!parsedCall.hasMatch()){
if(n) *n = 0;
return frame;
}
@ -830,26 +846,33 @@ QString Varicode::packBeaconMessage(QString const &callsign, QString const &extr
packed_extra = Varicode::packGrid(extra);
}
if(isCQ){
if(isBCN){
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;
}
if(n) *n = parsedText.captured(0).length();
return frame;
}
QStringList Varicode::unpackBeaconMessage(const QString &text, bool * isCQ){
QStringList Varicode::unpackBeaconMessage(const QString &text, bool * isBCN){
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)));
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;
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);
}
QStringList Varicode::unpackCompoundMessage(const QString &text, quint16 *pNum){
QStringList Varicode::unpackCompoundFrame(const QString &text, quint16 *pNum){
QStringList unpacked;
if(text.length() < 13 || text.contains(" ")){

View File

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