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 <QDebug>
#include <varicode.h>
extern "C" {
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 ()
, 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

View File

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

View File

@ -2030,6 +2030,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
foxTest();
return;
}
break;
case Qt::Key_E:
if(e->modifiers() & Qt::ShiftModifier) {
ui->txFirstCheckBox->setChecked(false);
@ -3150,9 +3151,12 @@ void MainWindow::readFromStdout() //readFromStdout
d.firstCall = decodedtext.CQersCall();
if(d.firstCall.isEmpty()){
auto words = decodedtext.messageWords();
if(words.length() > 1){
if(words.length() == 2){
d.firstCall = words.at(0);
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.snr = decodedtext.snr();
m_bandActivity[offset].append(d);
while(m_bandActivity[offset].count() > 10){
m_bandActivity[offset].removeFirst();
}
@ -3234,36 +3239,26 @@ void MainWindow::readFromStdout() //readFromStdout
// TOD0: jsherer - parse for commands?
// KN4CRD K1JT ?
bool shouldParseDirected = false;
if(shouldParseDirected){
// can this be decoded as a directed message?
if(!decodedtext.isStandardMessage()){
QStringList parts = Varicode::unpackDirectedMessage(decodedtext.message());
bool shouldProcessDirected = true;
if(shouldProcessDirected && decodedtext.isDirectedMessage()){
auto parts = decodedtext.directedMessage();
if(!parts.isEmpty()){
if(parts.at(1) == m_config.my_callsign()){
CommandDetail d;
d.call = parts.at(0);
d.command = parts.at(2);
d.freq = decodedtext.frequencyOffset();
d.snr = decodedtext.snr();
d.utcTimestamp = QDateTime::currentDateTimeUtc();
m_rxCommandQueue.append(d);
CommandDetail d;
d.from = parts.at(0);
d.to = parts.at(1);
d.command = parts.at(2);
d.freq = decodedtext.frequencyOffset();
d.snr = decodedtext.snr();
d.utcTimestamp = QDateTime::currentDateTimeUtc();
m_rxCommandQueue.append(d);
// TODO: jsherer - don't hardcode this here...
if(m_txFrameQueue.isEmpty() && QDateTime::currentDateTimeUtc().secsTo(m_nextBeacon) > 0){
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);
}
}
}
}
CallDetail cd;
cd.call = d.from;
cd.grid = "";
cd.snr = decodedtext.snr();
cd.freq = decodedtext.frequencyOffset();
cd.utcTimestamp = d.utcTimestamp;
m_callActivity[cd.call] = cd;
}
}
}
@ -4059,11 +4054,13 @@ void MainWindow::guiUpdate()
m_rxDirty = true;
}
// once per second
displayDialFrequency ();
displayActivity();
}
// once per 100ms
displayTransmit();
m_iptt0=g_iptt;
@ -5234,7 +5231,7 @@ void MainWindow::clearActivity(){
m_rxDirectedCache.clear();
m_rxFrameBlockNumbers.clear();
m_rxFrameQueue.clear();
m_rxCommandQueue.clear();
clearTableWidget(ui->tableWidgetCalls);
clearTableWidget(ui->tableWidgetRXAll);
@ -5545,7 +5542,7 @@ void MainWindow::scheduleBeacon(bool first){
timestamp = timestamp.addSecs(delta);
// 25% of the time, switch intervals
float prob = (float) qrand() / (RAND_MAX+1);
float prob = (float) qrand() / (RAND_MAX);
if(prob < 0.25){
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));
ui->extFreeTextMsgEdit->setPlainText(message);
//ui->extFreeTextMsgEdit->setPlainText(message);
addMessageText(message);
ui->startTxButton->setChecked(true);
scheduleBeacon();
@ -7947,6 +7946,64 @@ void MainWindow::displayActivity(){
block = logRxTxMessageText(d.utcTimestamp, d.isFree, d.text, d.freq, false, 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)

View File

@ -643,7 +643,8 @@ private:
struct CommandDetail
{
QString call;
QString from;
QString to;
QString command;
int freq;
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)));
quint8 packed_cmd = Varicode::bitsToInt(Varicode::strToBits(bits.mid(59, 5)));
unpacked.append(Varicode::unpackCallsign(packed_from));
unpacked.append(Varicode::unpackCallsign(packed_to));
unpacked.append(Varicode::unpackCallsign(packed_from).trimmed());
unpacked.append(Varicode::unpackCallsign(packed_to).trimmed());
unpacked.append(QString(cmds.at(packed_cmd & 7)));
return unpacked;