Added station message command processing

This commit is contained in:
Jordan Sherer 2018-07-19 02:09:19 -04:00
parent 50a3a56d2d
commit 512dffabf4
5 changed files with 102 additions and 32 deletions

View File

@ -3264,7 +3264,7 @@ void MainWindow::readFromStdout() //readFromStdout
CommandDetail d; CommandDetail d;
d.from = parts.at(0); d.from = parts.at(0);
d.to = parts.at(1); d.to = parts.at(1);
d.command = parts.at(2); d.cmd = 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();
@ -5311,7 +5311,11 @@ int MainWindow::logRxTxMessageText(QDateTime date, bool isFree, QString text, in
return c.blockNumber(); return c.blockNumber();
} }
void MainWindow::addMessageText(QString text){ void MainWindow::addMessageText(QString text, bool clear){
if(clear){
ui->extFreeTextMsgEdit->clear();
}
// TODO: jsherer - check to make sure we're not transmitting currently // TODO: jsherer - check to make sure we're not transmitting currently
QTextCursor c = ui->extFreeTextMsgEdit->textCursor(); QTextCursor c = ui->extFreeTextMsgEdit->textCursor();
if(c.hasSelection()){ if(c.hasSelection()){
@ -5437,6 +5441,17 @@ void MainWindow::on_extFreeTextMsgEdit_currentTextChanged (QString const& text)
} }
} }
QString trimWithPeriods(QString value){
QRegularExpression re("^\\s+");
auto match = re.match(value);
if(match.hasMatch()){
int count = match.captured(0).length();
return value.replace(0, count, QString(".").repeated(count));
}
return value;
}
QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const& text){ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const& text){
QStringList frames; QStringList frames;
QStringList lines; QStringList lines;
@ -5473,7 +5488,7 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
if(!line.startsWith(frame)){ if(!line.startsWith(frame)){
line = ( line = (
line.left(frame.length()).replace(':', ' ') + line.left(frame.length()).replace(':', ' ') + // is this the only case where we could have a mismatch?
line.mid(frame.length()) line.mid(frame.length())
).trimmed(); ).trimmed();
} }
@ -5496,6 +5511,11 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
foreach(auto frame, frames){ foreach(auto frame, frames){
qDebug() << "->" << frame; qDebug() << "->" << frame;
} }
qDebug() << "lines:";
foreach(auto frame, frames){
qDebug() << "->" << frame;
}
#endif #endif
return {frames,lines}; return {frames,lines};
@ -6842,7 +6862,7 @@ void MainWindow::on_queryButton_pressed(){
return; return;
} }
addMessageText(QString("%1?").arg(selectedCall)); addMessageText(QString("%1?").arg(selectedCall), true);
}); });
auto qthAction = menu->addAction("@ - What is your QTH?"); auto qthAction = menu->addAction("@ - What is your QTH?");
@ -6853,12 +6873,47 @@ void MainWindow::on_queryButton_pressed(){
return; return;
} }
addMessageText(QString("%1@").arg(selectedCall)); addMessageText(QString("%1@").arg(selectedCall), true);
});
auto stationAction = menu->addAction("&& - What is your station message?");
connect(stationAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
if(selectedCall.isEmpty()){
return;
}
addMessageText(QString("%1&").arg(selectedCall), true);
}); });
menu->addAction("$ - What stations are you hearing?")->setEnabled(false); menu->addAction("$ - What stations are you hearing?")->setEnabled(false);
menu->addAction("&& - What is your message?")->setEnabled(false);
menu->addAction("| - Relay the following message")->setEnabled(false); menu->addAction("| - Please relay the following message")->setEnabled(false);
menu->addSeparator();
auto rrAction = menu->addAction("RR - I acknowledge your last transmission");
connect(rrAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
if(selectedCall.isEmpty()){
return;
}
addMessageText(QString("%1 RR").arg(selectedCall), true);
});
auto agnAction = menu->addAction("AGN? - Please repeat your last transmission");
connect(agnAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
if(selectedCall.isEmpty()){
return;
}
addMessageText(QString("%1 AGN?").arg(selectedCall), true);
});
ui->queryButton->setMenu(menu); ui->queryButton->setMenu(menu);
ui->queryButton->showMenu(); ui->queryButton->showMenu();
@ -8086,7 +8141,6 @@ void MainWindow::displayActivity(bool force){
} }
// Command Activity // Command Activity
if(m_txFrameQueue.isEmpty() && !m_rxCommandQueue.isEmpty()){ if(m_txFrameQueue.isEmpty() && !m_rxCommandQueue.isEmpty()){
@ -8097,10 +8151,10 @@ void MainWindow::displayActivity(bool force){
while(!m_rxCommandQueue.isEmpty()){ while(!m_rxCommandQueue.isEmpty()){
auto d = m_rxCommandQueue.dequeue(); auto d = m_rxCommandQueue.dequeue();
qDebug() << "processing command" << d.from << d.to << d.command << d.freq; qDebug() << "processing command" << d.from << d.to << d.cmd << d.freq;
// we're only processing queries at this point // we're only processing a subset of queries at this point
if(d.command != "?" && d.command != "@"){ if(!Varicode::isCommandAllowed(d.cmd)){
continue; continue;
} }
@ -8110,17 +8164,25 @@ void MainWindow::displayActivity(bool force){
} }
// TODO: jsherer - check to make sure we haven't replied to their allcall recently (in the past 5 minutes) // TODO: jsherer - check to make sure we haven't replied to their allcall recently (in the past 5 minutes)
if(m_txAllcallCommandCache.contains(d.from) && m_txAllcallCommandCache[d.from]->secsTo(QDateTime::currentDateTimeUtc()) < 300){ if(d.to == "ALLCALL" && m_txAllcallCommandCache.contains(d.from) && m_txAllcallCommandCache[d.from]->secsTo(QDateTime::currentDateTimeUtc()) < 300){
continue; continue;
} }
// construct reply // construct reply
auto reply = QString("%1 %2 %3").arg(d.from).arg(m_config.my_callsign()); QString reply;
if(d.command == "?"){
reply = reply.arg(d.snr); if(d.cmd == "?"){
} else if(d.command == "@"){ reply = QString("%1 %2 %3").arg(d.from).arg(m_config.my_callsign()).arg(d.snr);
reply = reply.arg(m_config.my_grid());
} }
else if(d.cmd == "@"){
reply = QString("%1 %2 %3").arg(d.from).arg(m_config.my_callsign()).arg(m_config.my_grid());
}
else if(d.cmd == "&"){
reply = QString("%1 %2").arg(d.from).arg(m_config.my_station());
} else {
continue;
}
addMessageText(reply); addMessageText(reply);
// use the last frequency // use the last frequency

View File

@ -122,7 +122,7 @@ public slots:
void clearActivity(); void clearActivity();
int logRxTxMessageText(QDateTime date, bool isFree, QString text, int freq, bool tx, int block=-1); int logRxTxMessageText(QDateTime date, bool isFree, QString text, int freq, bool tx, int block=-1);
void addMessageText(QString text); void addMessageText(QString text, bool clear=false);
void resetMessage(); void resetMessage();
void resetMessageUI(); void resetMessageUI();
void createMessage(QString const& text); void createMessage(QString const& text);
@ -646,7 +646,7 @@ private:
{ {
QString from; QString from;
QString to; QString to;
QString command; QString cmd;
int freq; int freq;
QDateTime utcTimestamp; QDateTime utcTimestamp;
int snr; int snr;

View File

@ -1224,7 +1224,7 @@ background:yellow;
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string>Query</string> <string>Directed</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -4002,7 +4002,7 @@ list. The list can be maintained in Settings (F2).</string>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>960</width> <width>960</width>
<height>21</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">

View File

@ -38,21 +38,24 @@ QString callsign_alphabet = {"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ "};
QMap<QString, int> directed_cmds = { QMap<QString, int> directed_cmds = {
// any changes here need to be made also in the directed regular xpression for parsing // any changes here need to be made also in the directed regular xpression for parsing
{"?", 0 }, // query snr {"?", 0 }, // query snr
{"$", 1 }, // query stations heard //{"$", 1 }, // query stations heard
{"@", 2 }, // query qth {"@", 2 }, // query qth
{"&", 3 }, // query station message {"&", 3 }, // query station message
{"|", 4 }, // relay message //{"|", 4 }, // relay message
{":+", 5 }, // report +snr
{":-", 6 }, // report -snr //{"+", 5 }, // report +snr
{":ACK", 7 }, // ack message //{"-", 6 }, // report -snr
{":NACK", 8 }, // nack message
// ... // ...
{" ", 31 }, // send freetext {" RR", 29 }, // confirm message
{" AGN", 30 }, // repeat message
{" AGN?", 30 }, // repeat message
{" ", 31 }, // send freetext
}; };
QSet<int> allowed_cmds = {0, 2, 31}; QSet<int> allowed_cmds = {0, 2, 3, 29, 30, 31};
QRegularExpression directed_re(R"(^(?:(?<from>[A-Z0-9/]+):\s?)?(?<to>[A-Z0-9/]+)(?<cmd>([?$@&| ]|:N?ACK|:[-+])))"); QRegularExpression directed_re(R"(^(?:(?<from>[A-Z0-9/]+):\s?)?(?<to>[A-Z0-9/]+)(?<cmd>(\s(?:RR|AGN[?]?)|[?$@&| ])))");
QMap<QChar, QString> huff = { QMap<QChar, QString> huff = {
// char code weight // char code weight
@ -505,6 +508,10 @@ QString Varicode::unpackGrid(quint16 value){
return deg2grid(dlong, dlat).left(4); return deg2grid(dlong, dlat).left(4);
} }
bool Varicode::isCommandAllowed(const QString &cmd){
return directed_cmds.contains(cmd) && allowed_cmds.contains(directed_cmds[cmd]);
}
QString Varicode::packDirectedMessage(const QString &text, const QString &callsign, int *n){ QString Varicode::packDirectedMessage(const QString &text, const QString &callsign, int *n){
QString frame; QString frame;
@ -523,7 +530,7 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi
} }
bool validToCallsign = basecalls.contains(to) || QRegularExpression(callsign_pattern2).match(to).hasMatch(); bool validToCallsign = basecalls.contains(to) || QRegularExpression(callsign_pattern2).match(to).hasMatch();
if(!validToCallsign || !directed_cmds.contains(cmd) || !allowed_cmds.contains(directed_cmds[cmd])){ if(!validToCallsign || !Varicode::isCommandAllowed(cmd)){
*n = 0; *n = 0;
return frame; return frame;
} }
@ -553,6 +560,7 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi
frame = Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_extra & 31); frame = Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_extra & 31);
*n = match.captured(0).length(); *n = match.captured(0).length();
} }
return frame; return frame;
} }

View File

@ -11,7 +11,6 @@
#include <QString> #include <QString>
#include <QVector> #include <QVector>
class Varicode class Varicode
{ {
public: public:
@ -61,6 +60,7 @@ public:
static quint16 packGrid(QString const& value); static quint16 packGrid(QString const& value);
static QString unpackGrid(quint16 value); static QString unpackGrid(quint16 value);
static bool isCommandAllowed(const QString &cmd);
static QString packDirectedMessage(QString const& text, QString const& callsign, int *n); static QString packDirectedMessage(QString const& text, QString const& callsign, int *n);
static QStringList unpackDirectedMessage(QString const& text); static QStringList unpackDirectedMessage(QString const& text);
}; };