Working through QUERY MSG [id] and MSG commands to make it easier to work with the inbox
This commit is contained in:
parent
e0838a2164
commit
da41991171
219
mainwindow.cpp
219
mainwindow.cpp
@ -5728,7 +5728,7 @@ void MainWindow::addMessageText(QString text, bool clear, bool selectFirstPlaceh
|
|||||||
c.insertText(text);
|
c.insertText(text);
|
||||||
|
|
||||||
if(selectFirstPlaceholder){
|
if(selectFirstPlaceholder){
|
||||||
auto match = QRegularExpression("(\\[.+\\])").match(ui->extFreeTextMsgEdit->toPlainText());
|
auto match = QRegularExpression("(\\[[^\\]]+\\])").match(ui->extFreeTextMsgEdit->toPlainText());
|
||||||
if(match.hasMatch()){
|
if(match.hasMatch()){
|
||||||
c.setPosition(match.capturedStart());
|
c.setPosition(match.capturedStart());
|
||||||
c.setPosition(match.capturedEnd(), QTextCursor::KeepAnchor);
|
c.setPosition(match.capturedEnd(), QTextCursor::KeepAnchor);
|
||||||
@ -6949,8 +6949,8 @@ void MainWindow::sendHeartbeat(){
|
|||||||
processTxQueue();
|
processTxQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::sendHeartbeatAck(QString to, int snr){
|
void MainWindow::sendHeartbeatAck(QString to, int snr, QString extra){
|
||||||
auto message = QString("%1 ACK %2").arg(to).arg(Varicode::formatSNR(snr));
|
auto message = QString("%1 ACK %2 %3").arg(to).arg(Varicode::formatSNR(snr)).arg(extra).trimmed();
|
||||||
|
|
||||||
auto f = m_config.heartbeat_anywhere() ? -1 : findFreeFreqOffset(500, 1000, 50);
|
auto f = m_config.heartbeat_anywhere() ? -1 : findFreeFreqOffset(500, 1000, 50);
|
||||||
|
|
||||||
@ -7357,7 +7357,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
|||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto alertAction = menu->addAction(QString("%1>[MESSAGE] - Please save this message or relay it to its destination").arg(call).trimmed());
|
auto alertAction = menu->addAction(QString("%1>[MESSAGE] - Please relay this message to its destination").arg(call).trimmed());
|
||||||
alertAction->setDisabled(isAllCall);
|
alertAction->setDisabled(isAllCall);
|
||||||
connect(alertAction, &QAction::triggered, this, [this](){
|
connect(alertAction, &QAction::triggered, this, [this](){
|
||||||
|
|
||||||
@ -7509,19 +7509,6 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
|||||||
if(m_config.transmit_directed()) toggleTx(true);
|
if(m_config.transmit_directed()) toggleTx(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto tuAction = menu->addAction(QString("%1 TU - Thank You").arg(call).trimmed());
|
|
||||||
connect(tuAction, &QAction::triggered, this, [this](){
|
|
||||||
|
|
||||||
QString selectedCall = callsignSelected();
|
|
||||||
if(selectedCall.isEmpty()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addMessageText(QString("%1 TU").arg(selectedCall), true);
|
|
||||||
|
|
||||||
if(m_config.transmit_directed()) toggleTx(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto sevenThreeAction = menu->addAction(QString("%1 73 - I send my best regards").arg(call).trimmed());
|
auto sevenThreeAction = menu->addAction(QString("%1 73 - I send my best regards").arg(call).trimmed());
|
||||||
connect(sevenThreeAction, &QAction::triggered, this, [this](){
|
connect(sevenThreeAction, &QAction::triggered, this, [this](){
|
||||||
|
|
||||||
@ -9696,10 +9683,13 @@ void MainWindow::processCommandActivity() {
|
|||||||
c.movePosition(QTextCursor::StartOfBlock);
|
c.movePosition(QTextCursor::StartOfBlock);
|
||||||
c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||||
qDebug() << "should display directed message, erasing last rx activity line..." << c.selectedText();
|
qDebug() << "should display directed message, erasing last rx activity line..." << c.selectedText();
|
||||||
|
c.removeSelectedText();
|
||||||
c.deletePreviousChar();
|
c.deletePreviousChar();
|
||||||
c.deletePreviousChar();
|
c.deletePreviousChar();
|
||||||
|
/*
|
||||||
c.deleteChar();
|
c.deleteChar();
|
||||||
c.deleteChar();
|
c.deleteChar();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// log it to the display!
|
// log it to the display!
|
||||||
@ -9841,14 +9831,9 @@ void MainWindow::processCommandActivity() {
|
|||||||
|
|
||||||
// otherwise, as long as we're not an ACK...alert the user and either send an ACK or Message
|
// otherwise, as long as we're not an ACK...alert the user and either send an ACK or Message
|
||||||
} else if(!d.text.startsWith("ACK")) {
|
} else if(!d.text.startsWith("ACK")) {
|
||||||
QStringList calls;
|
|
||||||
QString callDePattern = {R"(\sDE\s(?<callsign>\b(?<prefix>[A-Z0-9]{1,4}\/)?(?<base>([0-9A-Z])?([0-9A-Z])([0-9])([A-Z])?([A-Z])?([A-Z])?)(?<suffix>\/[A-Z0-9]{1,4})?)\b)"};
|
// parse out the callsign path
|
||||||
QRegularExpression re(callDePattern);
|
auto calls = parseRelayPathCallsigns(d.from, d.text);
|
||||||
auto iter = re.globalMatch(text);
|
|
||||||
while(iter.hasNext()){
|
|
||||||
auto match = iter.next();
|
|
||||||
calls.prepend(match.captured("callsign"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// put these third party calls in the heard list
|
// put these third party calls in the heard list
|
||||||
foreach(auto call, calls){
|
foreach(auto call, calls){
|
||||||
@ -9862,7 +9847,6 @@ void MainWindow::processCommandActivity() {
|
|||||||
logCallActivity(cd, false);
|
logCallActivity(cd, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
calls.prepend(d.from);
|
|
||||||
d.relayPath = calls.join('>');
|
d.relayPath = calls.join('>');
|
||||||
|
|
||||||
reply = QString("%1 ACK").arg(d.relayPath);
|
reply = QString("%1 ACK").arg(d.relayPath);
|
||||||
@ -9883,7 +9867,7 @@ void MainWindow::processCommandActivity() {
|
|||||||
rd.bits = d.bits;
|
rd.bits = d.bits;
|
||||||
rd.cmd = first;
|
rd.cmd = first;
|
||||||
rd.freq = d.freq;
|
rd.freq = d.freq;
|
||||||
rd.from = d.relayPath;
|
rd.from = d.relayPath; // is this correct?
|
||||||
rd.text = d.text;
|
rd.text = d.text;
|
||||||
rd.to = d.to;
|
rd.to = d.to;
|
||||||
rd.utcTimestamp = d.utcTimestamp;
|
rd.utcTimestamp = d.utcTimestamp;
|
||||||
@ -9893,12 +9877,16 @@ void MainWindow::processCommandActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if STORE_RELAY_MSGS_TO_INBOX
|
||||||
// if we make it here, this is a message
|
// if we make it here, this is a message
|
||||||
addCommandToMyInbox(d);
|
addCommandToMyInbox(d);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ALERT_ON_NEW_MSG
|
||||||
QTimer::singleShot(500, this, [this, d](){
|
QTimer::singleShot(500, this, [this, d](){
|
||||||
MessageBox::information_message(this, QString("A new message was received at %1 UTC from %2").arg(d.utcTimestamp.time().toString()).arg(d.from));
|
MessageBox::information_message(this, QString("A new message was received at %1 UTC from %2").arg(d.utcTimestamp.time().toString()).arg(d.from));
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9943,19 +9931,69 @@ void MainWindow::processCommandActivity() {
|
|||||||
// PROCESS ACTIVE HEARTBEAT
|
// PROCESS ACTIVE HEARTBEAT
|
||||||
// if we have auto reply enabled and we are heartbeating and selcall is not enabled
|
// if we have auto reply enabled and we are heartbeating and selcall is not enabled
|
||||||
else if (d.cmd == " HB" && ui->autoReplyButton->isChecked() && ui->hbMacroButton->isChecked() && m_hbInterval > 0){
|
else if (d.cmd == " HB" && ui->autoReplyButton->isChecked() && ui->hbMacroButton->isChecked() && m_hbInterval > 0){
|
||||||
sendHeartbeatAck(d.from, d.snr);
|
|
||||||
|
// check to see if we have a message for a station who is heartbeating
|
||||||
|
QString extra;
|
||||||
|
auto mid = getNextMessageIdForCallsign(d.from);
|
||||||
|
if(mid != -1){
|
||||||
|
extra = QString("MSG ID %1").arg(mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendHeartbeatAck(d.from, d.snr, extra);
|
||||||
|
|
||||||
if(isAllCall){
|
if(isAllCall){
|
||||||
// since all pings are technically @ALLCALL, let's bump the allcall cache here...
|
// since all pings are technically @ALLCALL, let's bump the allcall cache here...
|
||||||
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 5);
|
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROCESS MSG
|
||||||
|
else if (d.cmd == " MSG"){
|
||||||
|
|
||||||
|
auto segs = d.text.split(" ");
|
||||||
|
if(segs.isEmpty()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
auto mid = segs.first().toInt(&ok);
|
||||||
|
if(!ok){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
segs.removeFirst();
|
||||||
|
if(segs.isEmpty()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto text = segs.join(" ");
|
||||||
|
|
||||||
|
qDebug() << "adding message" << mid << "to inbox" << text;
|
||||||
|
|
||||||
|
auto calls = parseRelayPathCallsigns(d.from, text);
|
||||||
|
|
||||||
|
d.cmd = " MSG ";
|
||||||
|
d.relayPath = calls.join(">");
|
||||||
|
d.text = text;
|
||||||
|
|
||||||
|
addCommandToMyInbox(d);
|
||||||
|
|
||||||
|
// make sure this is explicit
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROCESS ACKS
|
||||||
|
else if (d.cmd == " ACK"){
|
||||||
|
qDebug() << "skipping incoming ack" << d.text;
|
||||||
|
|
||||||
// make sure this is explicit
|
// make sure this is explicit
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROCESS BUFFERED CMD
|
// PROCESS BUFFERED CMD
|
||||||
else if (d.cmd == " CMD" && ui->autoReplyButton->isChecked()){
|
else if (d.cmd == " CMD"){
|
||||||
qDebug() << "skipping incoming command" << d.text;
|
qDebug() << "skipping incoming command" << d.text;
|
||||||
|
|
||||||
// make sure this is explicit
|
// make sure this is explicit
|
||||||
@ -9963,7 +10001,7 @@ void MainWindow::processCommandActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PROCESS BUFFERED QUERY
|
// PROCESS BUFFERED QUERY
|
||||||
else if (d.cmd == " QUERY" && ui->autoReplyButton->isChecked()){
|
else if (d.cmd == " QUERY"){
|
||||||
auto who = d.from;
|
auto who = d.from;
|
||||||
|
|
||||||
QStringList segs = d.text.split(" ");
|
QStringList segs = d.text.split(" ");
|
||||||
@ -10002,7 +10040,12 @@ void MainWindow::processCommandActivity() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
reply = QString("%1>MSG %2 %3 DE %4");
|
// mark as delivered (so subsequent HBs and QUERY MSGS don't receive this message)
|
||||||
|
msg.setType("DELIVERED");
|
||||||
|
inbox.set(mid, msg);
|
||||||
|
|
||||||
|
// and reply
|
||||||
|
reply = QString("%1 MSG %2 %3 DE %4");
|
||||||
reply = reply.arg(who);
|
reply = reply.arg(who);
|
||||||
reply = reply.arg(mid);
|
reply = reply.arg(mid);
|
||||||
reply = reply.arg(text);
|
reply = reply.arg(text);
|
||||||
@ -10014,21 +10057,11 @@ void MainWindow::processCommandActivity() {
|
|||||||
else if (d.cmd == " QUERY MSGS" && ui->autoReplyButton->isChecked()){
|
else if (d.cmd == " QUERY MSGS" && ui->autoReplyButton->isChecked()){
|
||||||
auto who = d.from;
|
auto who = d.from;
|
||||||
|
|
||||||
auto inbox = Inbox(inboxPath());
|
|
||||||
if(!inbox.open()){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this is an allcall or a directed call, check to see if we have a stored message for user.
|
// if this is an allcall or a directed call, check to see if we have a stored message for user.
|
||||||
// we reply yes if the user would be able to retreive a stored message
|
// we reply yes if the user would be able to retreive a stored message
|
||||||
auto v = inbox.values("STORE", "$.params.TO", who, 0, 10);
|
auto mid = getNextMessageIdForCallsign(who);
|
||||||
foreach(auto pair, v){
|
if(mid != -1){
|
||||||
auto params = pair.second.params();
|
reply = QString("%1 YES MSG ID %2").arg(who).arg(mid);
|
||||||
auto text = params.value("TEXT").toString().trimmed();
|
|
||||||
if(!text.isEmpty()){
|
|
||||||
reply = QString("%1 YES MSG %2").arg(who).arg(pair.first);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this is not an allcall and we have no messages, reply no.
|
// if this is not an allcall and we have no messages, reply no.
|
||||||
@ -10193,47 +10226,81 @@ void MainWindow::refreshInboxCounts(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::addCommandToMyInbox(CommandDetail d){
|
int MainWindow::addCommandToMyInbox(CommandDetail d){
|
||||||
// local cache for inbox count
|
// local cache for inbox count
|
||||||
m_rxInboxCountCache[d.from] = m_rxInboxCountCache.value(d.from, 0) + 1;
|
m_rxInboxCountCache[d.from] = m_rxInboxCountCache.value(d.from, 0) + 1;
|
||||||
|
|
||||||
// add it to my unread inbox
|
// add it to my unread inbox
|
||||||
addCommandToInboxStorage("UNREAD", d);
|
return addCommandToInboxStorage("UNREAD", d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::addCommandToInboxStorage(QString type, CommandDetail d){
|
int MainWindow::addCommandToInboxStorage(QString type, CommandDetail d){
|
||||||
// inbox:
|
// inbox:
|
||||||
auto inbox = Inbox(inboxPath());
|
auto inbox = Inbox(inboxPath());
|
||||||
if(inbox.open()){
|
if(!inbox.open()){
|
||||||
auto df = dialFrequency();
|
return -1;
|
||||||
|
|
||||||
QMap<QString, QVariant> v = {
|
|
||||||
{"UTC", QVariant(d.utcTimestamp.toString("yyyy-MM-dd hh:mm:ss"))},
|
|
||||||
{"TO", QVariant(d.to)},
|
|
||||||
{"FROM", QVariant(d.from)},
|
|
||||||
{"PATH", QVariant(d.relayPath)},
|
|
||||||
{"DIAL", QVariant((quint64)df)},
|
|
||||||
{"TDRIFT", QVariant(d.tdrift)},
|
|
||||||
{"OFFSET", QVariant(d.freq)},
|
|
||||||
{"CMD", QVariant(d.cmd)},
|
|
||||||
{"SNR", QVariant(d.snr)},
|
|
||||||
};
|
|
||||||
|
|
||||||
if(!d.grid.isEmpty()){
|
|
||||||
v["GRID"] = QVariant(d.grid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!d.extra.isEmpty()){
|
|
||||||
v["EXTRA"] = QVariant(d.extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!d.text.isEmpty()){
|
|
||||||
v["TEXT"] = QVariant(d.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto m = Message(type, "", v);
|
|
||||||
inbox.append(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto df = dialFrequency();
|
||||||
|
|
||||||
|
QMap<QString, QVariant> v = {
|
||||||
|
{"UTC", QVariant(d.utcTimestamp.toString("yyyy-MM-dd hh:mm:ss"))},
|
||||||
|
{"TO", QVariant(d.to)},
|
||||||
|
{"FROM", QVariant(d.from)},
|
||||||
|
{"PATH", QVariant(d.relayPath)},
|
||||||
|
{"DIAL", QVariant((quint64)df)},
|
||||||
|
{"TDRIFT", QVariant(d.tdrift)},
|
||||||
|
{"OFFSET", QVariant(d.freq)},
|
||||||
|
{"CMD", QVariant(d.cmd)},
|
||||||
|
{"SNR", QVariant(d.snr)},
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!d.grid.isEmpty()){
|
||||||
|
v["GRID"] = QVariant(d.grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!d.extra.isEmpty()){
|
||||||
|
v["EXTRA"] = QVariant(d.extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!d.text.isEmpty()){
|
||||||
|
v["TEXT"] = QVariant(d.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto m = Message(type, "", v);
|
||||||
|
|
||||||
|
return inbox.append(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MainWindow::getNextMessageIdForCallsign(QString callsign){
|
||||||
|
auto inbox = Inbox(inboxPath());
|
||||||
|
if(!inbox.open()){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto v = inbox.values("STORE", "$.params.TO", callsign, 0, 10);
|
||||||
|
foreach(auto pair, v){
|
||||||
|
auto params = pair.second.params();
|
||||||
|
auto text = params.value("TEXT").toString().trimmed();
|
||||||
|
if(!text.isEmpty()){
|
||||||
|
return pair.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList MainWindow::parseRelayPathCallsigns(QString from, QString text){
|
||||||
|
QStringList calls;
|
||||||
|
QString callDePattern = {R"(\sDE\s(?<callsign>\b(?<prefix>[A-Z0-9]{1,4}\/)?(?<base>([0-9A-Z])?([0-9A-Z])([0-9])([A-Z])?([A-Z])?([A-Z])?)(?<suffix>\/[A-Z0-9]{1,4})?)\b)"};
|
||||||
|
QRegularExpression re(callDePattern);
|
||||||
|
auto iter = re.globalMatch(text);
|
||||||
|
while(iter.hasNext()){
|
||||||
|
auto match = iter.next();
|
||||||
|
calls.prepend(match.captured("callsign"));
|
||||||
|
}
|
||||||
|
calls.prepend(from);
|
||||||
|
return calls;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::processAlertReplyForCommand(CommandDetail d, QString from, QString cmd){
|
void MainWindow::processAlertReplyForCommand(CommandDetail d, QString from, QString cmd){
|
||||||
|
@ -284,7 +284,7 @@ private slots:
|
|||||||
void buildCQMenu(QMenu *menu);
|
void buildCQMenu(QMenu *menu);
|
||||||
void buildRepeatMenu(QMenu *menu, QPushButton * button, int * interval);
|
void buildRepeatMenu(QMenu *menu, QPushButton * button, int * interval);
|
||||||
void sendHeartbeat();
|
void sendHeartbeat();
|
||||||
void sendHeartbeatAck(QString to, int snr);
|
void sendHeartbeatAck(QString to, int snr, QString extra);
|
||||||
void on_hbMacroButton_toggled(bool checked);
|
void on_hbMacroButton_toggled(bool checked);
|
||||||
void on_hbMacroButton_clicked();
|
void on_hbMacroButton_clicked();
|
||||||
void sendCQ(bool repeat=false);
|
void sendCQ(bool repeat=false);
|
||||||
@ -952,8 +952,10 @@ private:
|
|||||||
void processCommandActivity();
|
void processCommandActivity();
|
||||||
QString inboxPath();
|
QString inboxPath();
|
||||||
void refreshInboxCounts();
|
void refreshInboxCounts();
|
||||||
void addCommandToMyInbox(CommandDetail d);
|
int addCommandToMyInbox(CommandDetail d);
|
||||||
void addCommandToInboxStorage(QString type, CommandDetail d);
|
int addCommandToInboxStorage(QString type, CommandDetail d);
|
||||||
|
int getNextMessageIdForCallsign(QString callsign);
|
||||||
|
QStringList parseRelayPathCallsigns(QString from, QString text);
|
||||||
void processAlertReplyForCommand(CommandDetail d, QString from, QString cmd);
|
void processAlertReplyForCommand(CommandDetail d, QString from, QString cmd);
|
||||||
void processSpots();
|
void processSpots();
|
||||||
void processTxQueue();
|
void processTxQueue();
|
||||||
|
81
varicode.cpp
81
varicode.cpp
@ -45,73 +45,71 @@ QString alphanumeric = {"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /@"}; // callsign
|
|||||||
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
|
||||||
// ?*^&@
|
// ?*^&@
|
||||||
|
{" HB", -1 }, // this is my heartbeat (unused except for faux processing of HBs as directed commands)
|
||||||
|
|
||||||
{" SNR?", 0 }, // query snr
|
{" SNR?", 0 }, // query snr
|
||||||
{"?", 0 }, // compat
|
{"?", 0 }, // compat
|
||||||
|
|
||||||
{" QTH?", 1 }, // query qth
|
//{" ", 1 }, // unused
|
||||||
|
//{" ", 2 }, // unused
|
||||||
|
|
||||||
//{" ", 2 }, // unused
|
{" HEARING?", 3 }, // query station calls heard
|
||||||
|
|
||||||
{" HEARING?", 3 }, // query station calls heard
|
{" GRID?", 4 }, // query grid
|
||||||
|
|
||||||
{" GRID?", 4 }, // query grid
|
{">", 5 }, // relay message
|
||||||
|
|
||||||
{">", 5 }, // relay message
|
{" STATUS?", 6 }, // query idle message
|
||||||
|
|
||||||
{" STATUS?", 6 }, // query idle message
|
{" STATUS", 7 }, // this is my status
|
||||||
|
|
||||||
{" STATUS", 7 }, // this is my status
|
{" HEARING", 8 }, // these are the stations i'm hearing
|
||||||
|
|
||||||
{" HEARING", 8 }, // these are the stations i'm hearing
|
{" MSG", 9 }, // this is a complete message
|
||||||
|
|
||||||
{" TU", 9 }, // thank you
|
{" MSG TO:", 10 }, // store message at a station
|
||||||
|
|
||||||
{" HB", -1 }, // this is my heartbeat (unused except for faux processing of HBs as directed commands)
|
{" QUERY", 11 }, // generic query
|
||||||
|
|
||||||
{" MSG TO:", 10 }, // store message at a station
|
{" QUERY MSGS", 12 }, // do you have any stored messages?
|
||||||
|
|
||||||
{" QUERY", 11 }, // generic query
|
{" QUERY CALL", 13 }, // can you transmit a ping to callsign?
|
||||||
|
|
||||||
{" QUERY MSGS", 12 }, // do you have any stored messages?
|
{" APRS:", 14 }, // send an aprs packet
|
||||||
|
|
||||||
{" QUERY CALL", 13 }, // can you transmit a ping to callsign?
|
{" GRID", 15 }, // this is my current grid locator
|
||||||
|
|
||||||
{" APRS:", 14 }, // send an aprs packet
|
{" QTH?", 16 }, // what is your qth message?
|
||||||
|
{" QTH", 17 }, // this is my qth message
|
||||||
|
|
||||||
{" GRID", 15 }, // this is my current grid locator
|
{" FB", 18 }, // fine business
|
||||||
|
{" HW CPY?", 19 }, // how do you copy?
|
||||||
|
{" SK", 20 }, // end of contact
|
||||||
|
{" RR", 21 }, // roger roger
|
||||||
|
|
||||||
//{" ", 16 }, // unused
|
{" QSL?", 22 }, // do you copy?
|
||||||
|
{" QSL", 23 }, // i copy
|
||||||
|
|
||||||
{" QTH", 17 }, // this is my qth message
|
{" CMD", 24 }, // command
|
||||||
|
|
||||||
{" FB", 18 }, // fine business
|
{" SNR", 25 }, // seen a station at the provided snr
|
||||||
{" HW CPY?", 19 }, // how do you copy?
|
{" NO", 26 }, // negative confirm
|
||||||
{" SK", 20 }, // end of contact
|
{" YES", 27 }, // confirm
|
||||||
{" RR", 21 }, // roger roger
|
{" 73", 28 }, // best regards, end of contact
|
||||||
{" QSL?", 22 }, // do you copy?
|
{" ACK", 29 }, // acknowledge
|
||||||
{" QSL", 23 }, // i copy
|
{" AGN?", 30 }, // repeat message
|
||||||
|
{" ", 31 }, // send freetext (weird artifact)
|
||||||
{" CMD", 24 }, // open ended command
|
{" ", 31 }, // send freetext
|
||||||
|
|
||||||
{" SNR", 25 }, // seen a station at the provided snr
|
|
||||||
{" NO", 26 }, // negative confirm
|
|
||||||
{" YES", 27 }, // confirm
|
|
||||||
{" 73", 28 }, // best regards, end of contact
|
|
||||||
{" ACK", 29 }, // acknowledge
|
|
||||||
{" AGN?", 30 }, // repeat message
|
|
||||||
{" ", 31 }, // send freetext (weird artifact)
|
|
||||||
{" ", 31 }, // send freetext
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// commands allowed to be processed
|
// commands allowed to be processed
|
||||||
QSet<int> allowed_cmds = {-1, 0, 1, /*2,*/ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /*16,*/ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
QSet<int> allowed_cmds = {-1, 0, /*1,*/ /*2,*/ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||||
|
|
||||||
// commands that result in an autoreply (which can be relayed)
|
// commands that result in an autoreply (which can be relayed)
|
||||||
QSet<int> autoreply_cmds = {0, 1, 3, 4, 6, 10, 11, 12, 13, 30};
|
QSet<int> autoreply_cmds = {0, 3, 4, 6, 9, 11, 12, 13, 16, 30};
|
||||||
|
|
||||||
// commands that should be buffered
|
// commands that should be buffered
|
||||||
QSet<int> buffered_cmds = {3, 5, /*6,*/ /*7,*/ 10, 11, 12, 13, 14, 15, 24};
|
QSet<int> buffered_cmds = {5, /*6,*/ /*7,*/ 9, 10, 11, 12, 13, 14, 15, 24};
|
||||||
|
|
||||||
// commands that may include an SNR value
|
// commands that may include an SNR value
|
||||||
QSet<int> snr_cmds = {25, 29};
|
QSet<int> snr_cmds = {25, 29};
|
||||||
@ -119,6 +117,7 @@ QSet<int> snr_cmds = {25, 29};
|
|||||||
// commands that are checksummed and their crc size
|
// commands that are checksummed and their crc size
|
||||||
QMap<int, int> checksum_cmds = {
|
QMap<int, int> checksum_cmds = {
|
||||||
{ 5, 16 },
|
{ 5, 16 },
|
||||||
|
{ 9, 16 },
|
||||||
{ 10, 16 },
|
{ 10, 16 },
|
||||||
{ 11, 16 },
|
{ 11, 16 },
|
||||||
{ 12, 16 },
|
{ 12, 16 },
|
||||||
@ -129,7 +128,7 @@ QMap<int, int> checksum_cmds = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)");
|
QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)");
|
||||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|MSG TO[:]|SNR[?]|QTH[?]|GRID[?]|STATUS[?]|HEARING[?]|(?:(?:STATUS|HEARING|QUERY CALL|QUERY MSGS|QUERY|CMD|ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|GRID|TU)(?=[ ]|$))|[?> ]))?");
|
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|MSG TO[:]|SNR[?]|QTH[?]|GRID[?]|STATUS[?]|HEARING[?]|(?:(?:STATUS|HEARING|QUERY CALL|QUERY MSGS|QUERY|CMD|MSG|ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|GRID)(?=[ ]|$))|[?> ]))?");
|
||||||
QString optional_grid_pattern = QString("(?<grid>\\s?[A-R]{2}[0-9]{2})?");
|
QString optional_grid_pattern = QString("(?<grid>\\s?[A-R]{2}[0-9]{2})?");
|
||||||
QString optional_extended_grid_pattern = QString("^(?<grid>\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?");
|
QString optional_extended_grid_pattern = QString("^(?<grid>\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?");
|
||||||
QString optional_num_pattern = QString("(?<num>(?<=SNR|ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
|
QString optional_num_pattern = QString("(?<num>(?<=SNR|ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
|
||||||
|
Loading…
Reference in New Issue
Block a user