Refactor message buffering for relay
This commit is contained in:
parent
f67ea3803d
commit
9e9c996813
118
mainwindow.cpp
118
mainwindow.cpp
@ -62,7 +62,6 @@
|
||||
#include "ui_mainwindow.h"
|
||||
#include "moc_mainwindow.cpp"
|
||||
|
||||
#define TEST_ALL_OR_NOTHING 1 // 0
|
||||
|
||||
extern "C" {
|
||||
//----------------------------------------------------- C and Fortran routines
|
||||
@ -3247,39 +3246,9 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
d.snr = decodedtext.snr();
|
||||
m_bandActivity[offset].append(d);
|
||||
|
||||
#if TEST_ALL_OR_NOTHING
|
||||
if(m_messageCache.contains(d.freq/10*10)){
|
||||
m_messageCache[d.freq/10*10].second.append(d);
|
||||
|
||||
if(d.bits == Varicode::FT8CallLast){
|
||||
auto c = m_messageCache[d.freq/10*10].first;
|
||||
auto fs = m_messageCache[d.freq/10*10].second;
|
||||
if(!fs.isEmpty()){
|
||||
qDebug() << "MESSAGE COMPLETE:" << c.from << c.to;
|
||||
QString message;
|
||||
foreach(auto f, fs){
|
||||
message.append(f.text);
|
||||
}
|
||||
QString checksum = message.left(3);
|
||||
message = message.mid(3);
|
||||
bool valid = Varicode::checksum16Valid(checksum, message);
|
||||
qDebug() << "> CHECKSUM:" << checksum;
|
||||
qDebug() << "> MESSAGE:" << message;
|
||||
qDebug() << "> VALID:" << valid;
|
||||
|
||||
// TODO: jsherer - we should process this where all the other commands are processes...
|
||||
if(valid){
|
||||
addMessageText(QString("%1 ACK\n").arg(c.from), true);
|
||||
addMessageText(message, false);
|
||||
if(ui->autoReplyButton->isChecked()){
|
||||
toggleTx(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_messageCache.remove(d.freq/10*10);
|
||||
}
|
||||
if(m_messageBuffer.contains(d.freq/10*10)){
|
||||
m_messageBuffer[d.freq/10*10].msgs.append(d);
|
||||
}
|
||||
#endif
|
||||
|
||||
while(m_bandActivity[offset].count() > 10){
|
||||
m_bandActivity[offset].removeFirst();
|
||||
@ -3354,16 +3323,13 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
d.freq = decodedtext.frequencyOffset();
|
||||
d.snr = decodedtext.snr();
|
||||
d.utcTimestamp = QDateTime::currentDateTimeUtc();
|
||||
m_rxCommandQueue.append(d);
|
||||
|
||||
#if TEST_ALL_OR_NOTHING
|
||||
// TODO: jsherer - process this elsewhere?
|
||||
if(d.cmd == "|"){
|
||||
// cache the message buffer commands
|
||||
m_messageCache[d.freq/10*10].first = d;
|
||||
m_messageCache[d.freq/10*10].second.clear();
|
||||
if(Varicode::isCommandBuffered(d.cmd)){
|
||||
m_messageBuffer[d.freq/10*10].cmd = d;
|
||||
m_messageBuffer[d.freq/10*10].msgs.clear();
|
||||
} else {
|
||||
m_rxCommandQueue.append(d);
|
||||
}
|
||||
#endif
|
||||
|
||||
CallDetail cd;
|
||||
cd.call = d.from;
|
||||
@ -3416,7 +3382,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
}
|
||||
}
|
||||
|
||||
//Right (Rx Frequency) window
|
||||
//Right (Rx Frequency) window
|
||||
bool bDisplayRight=bAvgMsg;
|
||||
int audioFreq=decodedtext.frequencyOffset();
|
||||
|
||||
@ -5667,7 +5633,8 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
|
||||
QString stdFrame = parseFT8Message(line, &isFree);
|
||||
|
||||
int n = 0;
|
||||
QString dirFrame = Varicode::packDirectedMessage(line, basecall, &n);
|
||||
QString dirCmd;
|
||||
QString dirFrame = Varicode::packDirectedMessage(line, basecall, &dirCmd, &n);
|
||||
|
||||
int m = 0;
|
||||
QString datFrame = Varicode::packDataMessage(line.left(21) + "\x04", &m); // 63 / 3 = 21 (maximum number of 3bit chars we could possibly stuff in here)
|
||||
@ -5724,15 +5691,10 @@ QPair<QStringList, QStringList> MainWindow::buildFT8MessageFrames(QString const&
|
||||
lines.append(line.left(n) + " ");
|
||||
line = line.mid(n);
|
||||
|
||||
#if TEST_ALL_OR_NOTHING
|
||||
// TODO: jsherer - don't do this... refactor pack to return the packed frame _and_ its components instead
|
||||
if(Varicode::unpackDirectedMessage(dirFrame).at(2) == "|"){
|
||||
// TODO: jsherer - this is how we can add 16-bit checksum to the message, just encode it in the data...
|
||||
if(!line.isEmpty()){
|
||||
line = Varicode::checksum16(line) + line;
|
||||
if(Varicode::isCommandBuffered(dirCmd) && !line.isEmpty()){
|
||||
// TODO: jsherer - this is how we can add 16-bit checksum to the message, just encode it in the data...
|
||||
line = Varicode::checksum16(line) + " " + line;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(useDat){
|
||||
@ -7254,7 +7216,17 @@ void MainWindow::buildQueryMenu(QMenu * menu){
|
||||
toggleTx(true);
|
||||
});
|
||||
|
||||
//menu->addAction("| - Please relay the following message")->setEnabled(false);
|
||||
auto retransmitAction = menu->addAction("|message - Please ACK and retransmit the following message");
|
||||
retransmitAction->setDisabled(isAllCall);
|
||||
connect(retransmitAction, &QAction::triggered, this, [this](){
|
||||
|
||||
QString selectedCall = callsignSelected();
|
||||
if(selectedCall.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
addMessageText(QString("%1|").arg(selectedCall), true);
|
||||
});
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
@ -8634,9 +8606,36 @@ void MainWindow::displayActivity(bool force){
|
||||
}
|
||||
}
|
||||
|
||||
// Buffered Activity
|
||||
foreach(auto freq, m_messageBuffer.keys()){
|
||||
auto buffer = m_messageBuffer[freq];
|
||||
|
||||
if(buffer.msgs.isEmpty()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(buffer.msgs.last().bits == Varicode::FT8Call){
|
||||
continue;
|
||||
}
|
||||
|
||||
QString message;
|
||||
foreach(auto part, buffer.msgs){
|
||||
message.append(part.text);
|
||||
}
|
||||
|
||||
QString checksum = message.left(3);
|
||||
message = message.mid(4);
|
||||
|
||||
if(Varicode::checksum16Valid(checksum, message)){
|
||||
buffer.cmd.text = message;
|
||||
m_rxCommandQueue.append(buffer.cmd);
|
||||
}
|
||||
|
||||
// regardless of valid or not, remove the "complete" buffered message from the buffer cache
|
||||
m_messageBuffer.remove(freq);
|
||||
}
|
||||
|
||||
// Command Activity
|
||||
|
||||
if(m_txFrameQueue.isEmpty() && !m_rxCommandQueue.isEmpty()){
|
||||
int f = currentFreq();
|
||||
|
||||
@ -8703,7 +8702,8 @@ void MainWindow::displayActivity(bool force){
|
||||
}
|
||||
// QUERIED STATIONS HEARD
|
||||
else if(d.cmd == "$" && !isAllCall){
|
||||
|
||||
int i = 0;
|
||||
int maxStations = 4;
|
||||
auto calls = m_callActivity.keys();
|
||||
qSort(calls.begin(), calls.end(), [this](QString const &a, QString const &b){
|
||||
auto left = m_callActivity[a];
|
||||
@ -8713,14 +8713,24 @@ void MainWindow::displayActivity(bool force){
|
||||
|
||||
QStringList lines;
|
||||
foreach(auto call, calls){
|
||||
if(i >= maxStations){
|
||||
break;
|
||||
}
|
||||
if(Radio::base_callsign(call) == Radio::base_callsign(m_config.my_callsign())){
|
||||
continue;
|
||||
}
|
||||
|
||||
auto d = m_callActivity[call];
|
||||
lines.append(QString("%1 SNR %2").arg(Radio::base_callsign(call)).arg(Varicode::formatSNR(d.snr)));
|
||||
i++;
|
||||
}
|
||||
reply = lines.join('\n');
|
||||
}
|
||||
// PROCESS RETRANSMIT
|
||||
else if(d.cmd == "|" && !isAllCall){
|
||||
// TODO: jsherer - perhaps parse d.text and ensure it is a valid message?
|
||||
reply = QString("%1 ACK\n%2").arg(d.from).arg(d.text);
|
||||
}
|
||||
|
||||
if(reply.isEmpty()){
|
||||
continue;
|
||||
|
@ -656,6 +656,7 @@ private:
|
||||
int freq;
|
||||
QDateTime utcTimestamp;
|
||||
int snr;
|
||||
QString text;
|
||||
};
|
||||
|
||||
struct ActivityDetail
|
||||
@ -670,6 +671,11 @@ private:
|
||||
int snr;
|
||||
};
|
||||
|
||||
struct MessageBuffer {
|
||||
CommandDetail cmd;
|
||||
QList<ActivityDetail> msgs;
|
||||
};
|
||||
|
||||
bool m_rxDirty;
|
||||
int m_txFrameCount;
|
||||
QString m_lastTxMessage;
|
||||
@ -686,7 +692,7 @@ private:
|
||||
QCache<QString, int> m_rxCallCache; // call -> last freq seen
|
||||
QMap<int, int> m_rxFrameBlockNumbers; // freq -> block
|
||||
QMap<int, QList<ActivityDetail>> m_bandActivity; // freq -> [(text, last timestamp), ...]
|
||||
QMap<int, QPair<CommandDetail, QList<ActivityDetail>>> m_messageCache; // freq -> (cmd, [frames, ...])
|
||||
QMap<int, MessageBuffer> m_messageBuffer; // freq -> (cmd, [frames, ...])
|
||||
QMap<QString, CallDetail> m_callActivity; // call -> (last freq, last timestamp)
|
||||
QSet<QString> m_callSeenBeacon; // call
|
||||
int m_previousFreq;
|
||||
|
15
varicode.cpp
15
varicode.cpp
@ -65,6 +65,8 @@ QMap<QString, int> directed_cmds = {
|
||||
|
||||
QSet<int> allowed_cmds = {0, 1, 2, 3, 4, 5, 6, /*7,*/ 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||
|
||||
QSet<int> buffered_cmds = {6, 7};
|
||||
|
||||
QRegularExpression directed_re("^"
|
||||
"(?<to>[A-Z0-9/]+)"
|
||||
"(?<cmd>\\s?(?:AGN[?]|RR|73|YES|NO|SNR|PWR|ACK|[?@&$^%|! ]))"
|
||||
@ -679,6 +681,10 @@ bool Varicode::isCommandAllowed(const QString &cmd){
|
||||
return directed_cmds.contains(cmd) && allowed_cmds.contains(directed_cmds[cmd]);
|
||||
}
|
||||
|
||||
bool Varicode::isCommandBuffered(const QString &cmd){
|
||||
return directed_cmds.contains(cmd) && buffered_cmds.contains(directed_cmds[cmd]);
|
||||
}
|
||||
|
||||
QString Varicode::packCompoundMessage(const QString &baseCallsign, const QString &fix, bool isPrefix, quint16 num){
|
||||
QString frame;
|
||||
|
||||
@ -751,7 +757,7 @@ QStringList Varicode::unpackCompoundMessage(const QString &text){
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
QString Varicode::packDirectedMessage(const QString &text, const QString &baseCallsign, int *n){
|
||||
QString Varicode::packDirectedMessage(const QString &text, const QString &baseCallsign, QString * pCmd, int *n){
|
||||
QString frame;
|
||||
|
||||
auto match = directed_re.match(text);
|
||||
@ -824,6 +830,7 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &baseCa
|
||||
Varicode::intToBits(packed_cmd % 32, 5)
|
||||
);
|
||||
|
||||
if(pCmd) *pCmd = cmd;
|
||||
if(n) *n = match.captured(0).length();
|
||||
return Varicode::pack64bits(Varicode::bitsToInt(bits)) + Varicode::pack5bits(packed_extra % 32);
|
||||
}
|
||||
@ -853,10 +860,12 @@ QStringList Varicode::unpackDirectedMessage(const QString &text){
|
||||
quint8 packed_cmd = Varicode::bitsToInt(Varicode::strToBits(bits.mid(59, 5)));
|
||||
|
||||
QString from = Varicode::unpackCallsign(packed_from).trimmed();
|
||||
QString to = Varicode::unpackCallsign(packed_to).trimmed();
|
||||
QString cmd = directed_cmds.key(packed_cmd % 32);
|
||||
|
||||
unpacked.append(from);
|
||||
unpacked.append(Varicode::unpackCallsign(packed_to).trimmed());
|
||||
unpacked.append(directed_cmds.key(packed_cmd % 32));
|
||||
unpacked.append(to);
|
||||
unpacked.append(cmd);
|
||||
|
||||
int num = (num_flag ? -1 : 1) * extra;
|
||||
if(num != -31){
|
||||
|
@ -76,11 +76,12 @@ public:
|
||||
static QString unpackGrid(quint16 value);
|
||||
|
||||
static bool isCommandAllowed(const QString &cmd);
|
||||
static bool isCommandBuffered(const QString &cmd);
|
||||
|
||||
static QString packCompoundMessage(const QString &baseCallsign, const QString &fix, bool isPrefix, quint16 num);
|
||||
static QStringList unpackCompoundMessage(const QString &text);
|
||||
|
||||
static QString packDirectedMessage(QString const& text, QString const& callsign, int *n);
|
||||
static QString packDirectedMessage(QString const& text, QString const& callsign, QString * pCmd, int *n);
|
||||
static QStringList unpackDirectedMessage(QString const& text);
|
||||
|
||||
static QString packDataMessage(QString const& text, int *n);
|
||||
|
Loading…
Reference in New Issue
Block a user