diff --git a/decodedtext.cpp b/decodedtext.cpp index 3523266..ea72032 100644 --- a/decodedtext.cpp +++ b/decodedtext.cpp @@ -51,7 +51,7 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString , grid_c_string.constData () , 22, 6); } -}; +} QStringList DecodedText::messageWords () const { diff --git a/decodedtext.h b/decodedtext.h index 93ef67e..4780b94 100644 --- a/decodedtext.h +++ b/decodedtext.h @@ -32,6 +32,7 @@ public: explicit DecodedText (QString const& message, bool, QString const& my_grid); QString string() const { return string_; }; + QString message() const { return message_; }; QStringList messageWords () const; int indexOf(QString s) const { return string_.indexOf(s); }; int indexOf(QString s, int i) const { return string_.indexOf(s,i); }; diff --git a/mainwindow.cpp b/mainwindow.cpp index 6069b92..18e1a5e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3166,12 +3166,50 @@ void MainWindow::readFromStdout() //readFromStdout // K1JT KN4CRD R-12 // DE KN4CRD // KN4CRD - QString messageText = decodedtext.string(); + + QStringList callsigns = Varicode::parseCallsigns(decodedtext.message()); + if(!callsigns.isEmpty()){ + // one callsign + // de [from] + // cq [from] + + // two callsigns + // [from]: [to] ... + // [to] [from] [grid|signal] + + QStringList grids = Varicode::parseGrids(decodedtext.message()); + + // one callsigns are handled above... so we only need to handle two callsigns if it's a standard message + if(decodedtext.isStandardMessage()){ + if(callsigns.length() == 2){ + auto de_callsign = callsigns.last(); + + // TODO: jsherer - put this in a function to record a callsign... + CallDetail d; + d.call = de_callsign; + d.grid = !grids.empty() ? grids.first() : ""; + d.snr = decodedtext.snr(); + d.freq = decodedtext.frequencyOffset(); + d.utcTimestamp = QDateTime::currentDateTimeUtc(); + m_callActivity[de_callsign] = d; + + /* + //auto to_callsign = callsigns.first(); + CallDetail d2; + d2.call = to_callsign; + d2.grid = ""; + d2.snr = -100; + d2.freq = decodedtext.frequencyOffset(); + d2.utcTimestamp = QDateTime::currentDateTimeUtc(); + m_callActivity[to_callsign] = d2; + */ + } + } + } // TOD0: jsherer - parse for commands? // KN4CRD K1JT ? - } } @@ -5485,6 +5523,10 @@ void MainWindow::prepareBeacon(){ QString MainWindow::calculateDistance(QString const& grid) { + if(grid.isEmpty()){ + return QString(); + } + qint64 nsec = (QDateTime::currentMSecsSinceEpoch()/1000) % 86400; double utch=nsec/3600.0; int nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter; @@ -7662,6 +7704,9 @@ bool MainWindow::isMyCallIncluded(const QString &text){ } QString formatSNR(int snr){ + if(snr < -60 || snr > 60){ + return QString(); + } return QString("%1%2").arg(snr >= 0 ? "+" : "").arg(snr); } @@ -7718,10 +7763,6 @@ void MainWindow::displayActivity(){ continue; } - // TODO: jsherer - maybe parse for callsigns in the text? - // /^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/ - // from https://groups.io/g/hamauth/topic/call_sign_pattern_matching/6060598?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,0,6060598 - ui->tableWidgetRXAll->insertRow(ui->tableWidgetRXAll->rowCount()); auto offsetItem = new QTableWidgetItem(QString("%1").arg(offset)); diff --git a/varicode.cpp b/varicode.cpp index baa8f5f..cb90bd8 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -6,6 +6,46 @@ const int nalphabet = 41; QString alphabet = {"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?"}; +QString grid_pattern = {R"((?[A-R]{2}[0-9]{2})+)"}; +QString callsign_pattern1 = {R"((?[A-Z0-9/]{2,}))"}; +QString callsign_pattern2 = {R"((?(\d|[A-Z])+\/?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?))"}; + +QStringList Varicode::parseCallsigns(QString const &input){ + QStringList callsigns; + QRegularExpression re(callsign_pattern2); + QRegularExpressionMatchIterator iter = re.globalMatch(input); + while(iter.hasNext()){ + QRegularExpressionMatch match = iter.next(); + if(!match.hasMatch()){ + continue; + } + QString callsign = match.captured("callsign"); + QRegularExpression m(grid_pattern); + if(m.match(callsign).hasMatch()){ + continue; + } + callsigns.append(callsign); + } + return callsigns; +} + +QStringList Varicode::parseGrids(const QString &input){ + QStringList grids; + QRegularExpression re(grid_pattern); + QRegularExpressionMatchIterator iter = re.globalMatch(input); + while(iter.hasNext()){ + QRegularExpressionMatch match = iter.next(); + if(!match.hasMatch()){ + continue; + } + auto grid = match.captured("grid"); + if(grid == "RR73"){ + continue; + } + grids.append(grid); + } + return grids; +} QVector Varicode::intToBits(qint64 value, int expected){ QVector bits; @@ -62,7 +102,7 @@ QString Varicode::pack16bits(qint16 packed){ } qint32 Varicode::unpack32bits(QString const& value){ - return unpack16bits(value.left(3)) << 16 | unpack16bits(value.right(3)); + return (qint32)unpack16bits(value.left(3)) << 16 | unpack16bits(value.right(3)); } QString Varicode::pack32bits(qint32 packed){ @@ -72,10 +112,11 @@ QString Varicode::pack32bits(qint32 packed){ } qint64 Varicode::unpack64bits(QString const& value){ - return unpack16bits(value.left(6)) << 32 | unpack16bits(value.right(6)); + return (qint64)unpack16bits(value.left(6)) << 32 | unpack16bits(value.right(6)); } QString Varicode::pack64bits(qint64 packed){ qint32 a = (packed & 0xFFFFFFFF00000000) >> 32; qint32 b = packed & 0xFFFFFFFF; + return pack32bits(a) + pack32bits(b); } diff --git a/varicode.h b/varicode.h index fe21cbc..ca5b8e0 100644 --- a/varicode.h +++ b/varicode.h @@ -6,14 +6,21 @@ **/ #include +#include +#include #include #include + class Varicode { public: //Varicode(); + static QStringList parseCallsigns(QString const &input); + static QStringList parseGrids(QString const &input); + + QVector intToBits(qint64 value, int expected=0); qint64 bitsToInt(QVector const value);