Added station message command processing
This commit is contained in:
parent
50a3a56d2d
commit
512dffabf4
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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">
|
||||||
|
28
varicode.cpp
28
varicode.cpp
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user