Refactored directed code into decoded text so the rest of the app can use it as is.

This commit is contained in:
Jordan Sherer 2018-07-13 10:32:58 -04:00
parent 4140114d8d
commit a96216e2f8
5 changed files with 126 additions and 43 deletions

View File

@ -4,6 +4,8 @@
#include <QRegularExpression> #include <QRegularExpression>
#include <QDebug> #include <QDebug>
#include <varicode.h>
extern "C" { extern "C" {
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, fortran_charlen_t, fortran_charlen_t); bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, fortran_charlen_t, fortran_charlen_t);
} }
@ -51,6 +53,22 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
, grid_c_string.constData () , grid_c_string.constData ()
, 22, 6); , 22, 6);
} }
if(!is_standard_){
tryUnpackDirected();
}
}
void DecodedText::tryUnpackDirected(){
QStringList parts = Varicode::unpackDirectedMessage(message());
if(parts.isEmpty()){
return;
}
// replace it with the correct unpacked
message_ = QString("%1:%2%3").arg(parts.at(0), parts.at(1), parts.at(2));
directed_ = parts;
} }
QStringList DecodedText::messageWords () const QStringList DecodedText::messageWords () const

View File

@ -10,6 +10,7 @@
#define DECODEDTEXT_H #define DECODEDTEXT_H
#include <QString> #include <QString>
#include <QStringList>
@ -31,15 +32,20 @@ class DecodedText
public: public:
explicit DecodedText (QString const& message, bool, QString const& my_grid); explicit DecodedText (QString const& message, bool, QString const& my_grid);
QString string() const { return string_; }; void tryUnpackDirected();
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); };
QString mid(int f, int t) const { return string_.mid(f,t); };
QString left(int i) const { return string_.left(i); };
void clear() { string_.clear(); }; QStringList directedMessage() const { return directed_; }
bool isDirectedMessage() const { return !directed_.isEmpty(); }
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); }
QString mid(int f, int t) const { return string_.mid(f,t); }
QString left(int i) const { return string_.left(i); }
void clear() { string_.clear(); }
QString CQersCall() const; QString CQersCall() const;
@ -78,6 +84,7 @@ private:
column_mode = 19, column_mode = 19,
column_qsoText = 22 }; column_qsoText = 22 };
QStringList directed_;
QString string_; QString string_;
int padding_; int padding_;
bool contest_mode_; bool contest_mode_;

View File

@ -2030,6 +2030,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
foxTest(); foxTest();
return; return;
} }
break;
case Qt::Key_E: case Qt::Key_E:
if(e->modifiers() & Qt::ShiftModifier) { if(e->modifiers() & Qt::ShiftModifier) {
ui->txFirstCheckBox->setChecked(false); ui->txFirstCheckBox->setChecked(false);
@ -3150,9 +3151,12 @@ void MainWindow::readFromStdout() //readFromStdout
d.firstCall = decodedtext.CQersCall(); d.firstCall = decodedtext.CQersCall();
if(d.firstCall.isEmpty()){ if(d.firstCall.isEmpty()){
auto words = decodedtext.messageWords(); auto words = decodedtext.messageWords();
if(words.length() > 1){ if(words.length() == 2){
d.firstCall = words.at(0); d.firstCall = words.at(0);
d.secondCall = words.at(1); d.secondCall = words.at(1);
} else if(words.length() == 3){
d.firstCall = words.at(1);
d.secondCall = words.at(2);
} }
} }
@ -3161,6 +3165,7 @@ void MainWindow::readFromStdout() //readFromStdout
d.utcTimestamp = QDateTime::currentDateTimeUtc(); d.utcTimestamp = QDateTime::currentDateTimeUtc();
d.snr = decodedtext.snr(); d.snr = decodedtext.snr();
m_bandActivity[offset].append(d); m_bandActivity[offset].append(d);
while(m_bandActivity[offset].count() > 10){ while(m_bandActivity[offset].count() > 10){
m_bandActivity[offset].removeFirst(); m_bandActivity[offset].removeFirst();
} }
@ -3234,36 +3239,26 @@ void MainWindow::readFromStdout() //readFromStdout
// TOD0: jsherer - parse for commands? // TOD0: jsherer - parse for commands?
// KN4CRD K1JT ? // KN4CRD K1JT ?
bool shouldParseDirected = false; bool shouldProcessDirected = true;
if(shouldParseDirected){ if(shouldProcessDirected && decodedtext.isDirectedMessage()){
// can this be decoded as a directed message? auto parts = decodedtext.directedMessage();
if(!decodedtext.isStandardMessage()){
QStringList parts = Varicode::unpackDirectedMessage(decodedtext.message());
if(!parts.isEmpty()){ CommandDetail d;
if(parts.at(1) == m_config.my_callsign()){ d.from = parts.at(0);
CommandDetail d; d.to = parts.at(1);
d.call = parts.at(0); d.command = parts.at(2);
d.command = parts.at(2); d.freq = decodedtext.frequencyOffset();
d.freq = decodedtext.frequencyOffset(); d.snr = decodedtext.snr();
d.snr = decodedtext.snr(); d.utcTimestamp = QDateTime::currentDateTimeUtc();
d.utcTimestamp = QDateTime::currentDateTimeUtc(); m_rxCommandQueue.append(d);
m_rxCommandQueue.append(d);
// TODO: jsherer - don't hardcode this here... CallDetail cd;
if(m_txFrameQueue.isEmpty() && QDateTime::currentDateTimeUtc().secsTo(m_nextBeacon) > 0){ cd.call = d.from;
QString text = QString("%1 %2 %3").arg(d.call.trimmed()).arg(m_config.my_callsign().trimmed()).arg(d.snr); cd.grid = "";
cd.snr = decodedtext.snr();
setFreq4(d.freq, d.freq); cd.freq = decodedtext.frequencyOffset();
m_bandActivity[decodedtext.frequencyOffset()].last().text = QString("%1:%2%3").arg(d.call.trimmed()).arg(m_config.my_callsign()).arg(d.command); cd.utcTimestamp = d.utcTimestamp;
m_rxDirectedCache.insert(decodedtext.frequencyOffset()/10*10, new QDateTime(QDateTime::currentDateTimeUtc()), 25); m_callActivity[cd.call] = cd;
ui->extFreeTextMsgEdit->setPlainText(text);
ui->startTxButton->setChecked(true);
}
}
}
}
} }
} }
} }
@ -4059,11 +4054,13 @@ void MainWindow::guiUpdate()
m_rxDirty = true; m_rxDirty = true;
} }
// once per second
displayDialFrequency (); displayDialFrequency ();
displayActivity(); displayActivity();
} }
// once per 100ms
displayTransmit(); displayTransmit();
m_iptt0=g_iptt; m_iptt0=g_iptt;
@ -5234,7 +5231,7 @@ void MainWindow::clearActivity(){
m_rxDirectedCache.clear(); m_rxDirectedCache.clear();
m_rxFrameBlockNumbers.clear(); m_rxFrameBlockNumbers.clear();
m_rxFrameQueue.clear(); m_rxFrameQueue.clear();
m_rxCommandQueue.clear();
clearTableWidget(ui->tableWidgetCalls); clearTableWidget(ui->tableWidgetCalls);
clearTableWidget(ui->tableWidgetRXAll); clearTableWidget(ui->tableWidgetRXAll);
@ -5545,7 +5542,7 @@ void MainWindow::scheduleBeacon(bool first){
timestamp = timestamp.addSecs(delta); timestamp = timestamp.addSecs(delta);
// 25% of the time, switch intervals // 25% of the time, switch intervals
float prob = (float) qrand() / (RAND_MAX+1); float prob = (float) qrand() / (RAND_MAX);
if(prob < 0.25){ if(prob < 0.25){
timestamp = timestamp.addSecs(15); timestamp = timestamp.addSecs(15);
} }
@ -5580,7 +5577,9 @@ void MainWindow::prepareBeacon(){
QString message = QString("DE %1 %2\nDE %1 %2").arg(m_config.my_callsign()).arg(m_config.my_grid().mid(0, 4)); QString message = QString("DE %1 %2\nDE %1 %2").arg(m_config.my_callsign()).arg(m_config.my_grid().mid(0, 4));
ui->extFreeTextMsgEdit->setPlainText(message); //ui->extFreeTextMsgEdit->setPlainText(message);
addMessageText(message);
ui->startTxButton->setChecked(true); ui->startTxButton->setChecked(true);
scheduleBeacon(); scheduleBeacon();
@ -7947,6 +7946,64 @@ void MainWindow::displayActivity(){
block = logRxTxMessageText(d.utcTimestamp, d.isFree, d.text, d.freq, false, block); block = logRxTxMessageText(d.utcTimestamp, d.isFree, d.text, d.freq, false, block);
m_rxFrameBlockNumbers[freq] = block; m_rxFrameBlockNumbers[freq] = block;
} }
#if 0
// Directed Activity
// TODO: jsherer - don't hardcode this here...
if(m_txFrameQueue.isEmpty() && QDateTime::currentDateTimeUtc().secsTo(m_nextBeacon) > 0){
// construct a reply
QString text = QString("%1 %2 %3").arg(d.call.trimmed()).arg(m_config.my_callsign().trimmed()).arg(d.snr);
setFreq4(d.freq, d.freq);
m_bandActivity[decodedtext.frequencyOffset()].last().text = QString("%1:%2%3").arg(d.call.trimmed()).arg(m_config.my_callsign()).arg(d.command);
m_rxDirectedCache.insert(decodedtext.frequencyOffset()/10*10, new QDateTime(QDateTime::currentDateTimeUtc()), 25);
ui->extFreeTextMsgEdit->setPlainText(text);
ui->startTxButton->setChecked(true);
}
#endif
if(m_txFrameQueue.isEmpty()){
int f;
while(!m_rxCommandQueue.isEmpty()){
auto d = m_rxCommandQueue.head();
m_rxCommandQueue.pop_front();
qDebug() << "processing command" << d.from << d.to << d.command;
// we're only processing queries at this point
if(d.command != "?"){
continue;
}
// we're only processing allcall and our callsign at this point
if(d.to != "ALLCALL" && d.to != m_config.my_callsign().trimmed()){
continue;
}
// TODO: jsherer - check to make sure we haven't replied to their allcall recently
// construct reply
auto reply = QString("%1 %2 %3").arg(d.from).arg(d.to).arg(d.snr);
addMessageText(reply);
// use the last frequency
f = d.freq;
// if we're responding via allcall, pick a different frequency.
if(d.to == "ALLCALL"){
f = findFreeFreqOffset(qMax(0, f-100), qMin(f+100, 2500), 50);
}
}
// if we have beacon turned on, and it's more than 15 seconds away, automatically reply now
if(QDateTime::currentDateTimeUtc().secsTo(m_nextBeacon) > 15){
setFreq4(f, f);
ui->startTxButton->setChecked(true);
}
}
} }
void MainWindow::postWSPRDecode (bool is_new, QStringList parts) void MainWindow::postWSPRDecode (bool is_new, QStringList parts)

View File

@ -643,7 +643,8 @@ private:
struct CommandDetail struct CommandDetail
{ {
QString call; QString from;
QString to;
QString command; QString command;
int freq; int freq;
QDateTime utcTimestamp; QDateTime utcTimestamp;

View File

@ -402,8 +402,8 @@ QStringList Varicode::unpackDirectedMessage(const QString &text){
quint32 packed_to = Varicode::bitsToInt(Varicode::strToBits(bits.mid(31, 28))); quint32 packed_to = Varicode::bitsToInt(Varicode::strToBits(bits.mid(31, 28)));
quint8 packed_cmd = Varicode::bitsToInt(Varicode::strToBits(bits.mid(59, 5))); quint8 packed_cmd = Varicode::bitsToInt(Varicode::strToBits(bits.mid(59, 5)));
unpacked.append(Varicode::unpackCallsign(packed_from)); unpacked.append(Varicode::unpackCallsign(packed_from).trimmed());
unpacked.append(Varicode::unpackCallsign(packed_to)); unpacked.append(Varicode::unpackCallsign(packed_to).trimmed());
unpacked.append(QString(cmds.at(packed_cmd & 7))); unpacked.append(QString(cmds.at(packed_cmd & 7)));
return unpacked; return unpacked;