From faf653d8ba9354c874996847b19c36780ea8c933 Mon Sep 17 00:00:00 2001 From: Jordan Sherer Date: Wed, 23 Jan 2019 20:31:26 -0500 Subject: [PATCH] Added message storage and retreival --- mainwindow.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++------- mainwindow.h | 4 +- mainwindow.ui | 7 ++++ varicode.cpp | 19 +++++---- 4 files changed, 117 insertions(+), 23 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 85ee06a..1e16c4e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -805,17 +805,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->labDialFreqOffset->setCursor(QCursor(Qt::PointingHandCursor)); auto ldmp = new MousePressEater(); connect(ldmp, &MousePressEater::mousePressed, this, [this](QObject *, QMouseEvent *, bool *pProcessed){ - bool ok = false; - auto currentFreq = currentFreqOffset(); - QString newFreq = QInputDialog::getText(this, tr("Set Frequency Offset..."), - tr("Offset in Hz:"), QLineEdit::Normal, - QString("%1").arg(currentFreq), &ok).toUpper().trimmed(); - int offset = newFreq.toInt(&ok); - if(!ok){ - return; - } - - setFreqOffsetForRestore(offset, false); + on_actionSetOffset_triggered(); if(pProcessed) *pProcessed = true; }); @@ -2526,6 +2516,20 @@ void MainWindow::on_menuWindow_aboutToShow(){ ui->actionShow_Band_Heartbeats_and_ACKs->setEnabled(ui->actionShow_Band_Activity->isChecked()); } +void MainWindow::on_actionSetOffset_triggered(){ + bool ok = false; + auto currentFreq = currentFreqOffset(); + QString newFreq = QInputDialog::getText(this, tr("Set Frequency Offset..."), + tr("Offset in Hz:"), QLineEdit::Normal, + QString("%1").arg(currentFreq), &ok).toUpper().trimmed(); + int offset = newFreq.toInt(&ok); + if(!ok){ + return; + } + + setFreqOffsetForRestore(offset, false); +} + void MainWindow::on_actionShow_Fullscreen_triggered(bool checked){ auto state = windowState(); if(checked){ @@ -9875,7 +9879,7 @@ void MainWindow::processCommandActivity() { } // if we make it here, this is a message - addCommandToInbox(d); + addCommandToMyInbox(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)); @@ -9883,6 +9887,39 @@ void MainWindow::processCommandActivity() { } } + // PROCESS MESSAGE STORAGE + else if (d.cmd == " MSG TO:" && !isAllCall && !isGroupCall && !m_config.relay_off()){ + + // store message + QStringList segs = d.text.split(" "); + if(segs.isEmpty()){ + continue; + } + + auto to = segs.first(); + auto text = d.text.mid(to.length()).trimmed(); + + CommandDetail cd = {}; + cd.bits = d.bits; + cd.cmd = d.cmd; + cd.extra = d.extra; + cd.freq = d.freq; + cd.from = d.from; + cd.grid = d.grid; + cd.relayPath = d.relayPath; + cd.snr = d.snr; + cd.tdrift = d.tdrift; + cd.text = text; + cd.to = to; + cd.utcTimestamp = d.utcTimestamp; + + qDebug() << "storing message to" << to << ":" << text; + + addCommandToInboxStorage("STORE", cd); + + reply = QString("%1 ACK").arg(d.from); + } + // PROCESS AGN else if (d.cmd == " AGN?" && !isAllCall && !isGroupCall && !m_lastTxMessage.isEmpty()) { reply = m_lastTxMessage; @@ -9910,6 +9947,44 @@ void MainWindow::processCommandActivity() { continue; } + // PROCESS BUFFERED QUERY MSGS + else if (d.cmd == " QUERY MSGS" && ui->autoReplyButton->isChecked()){ + auto who = d.from; +#if 0 + QString key; + if(d.text.isEmpty()){ + key = who; + } else { + QStringList segs = d.text.trimmed().split(" "); + if(segs.isEmpty()){ + continue; + } + key = segs.first(); + } +#endif + + auto inbox = Inbox(inboxPath()); + if(!inbox.open()){ + continue; + } + + auto v = inbox.values("STORE", "$.params.TO", who, 0, 10); + foreach(auto pair, v){ + auto params = pair.second.params(); + auto text = params.value("TEXT").toString().trimmed(); + auto from = params.value("FROM").toString(); + if(!text.isEmpty()){ + // mark as delivered + pair.second.setType("DELIVERED"); + inbox.set(pair.first, pair.second); + + // and then reply with the text + reply = QString("%1>%2 DE %3").arg(who).arg(text).arg(from); + break; + } + } + } + // PROCESS BUFFERED QUERY CALL else if (d.cmd == " QUERY CALL" && ui->autoReplyButton->isChecked()){ auto who = d.text; @@ -10091,10 +10166,15 @@ void MainWindow::refreshInboxCounts(){ } } -void MainWindow::addCommandToInbox(CommandDetail d){ - // legacy +void MainWindow::addCommandToMyInbox(CommandDetail d){ + // local cache for inbox count m_rxInboxCountCache[d.from] = m_rxInboxCountCache.value(d.from, 0) + 1; + // add it to my unread inbox + addCommandToInboxStorage("UNREAD", d); +} + +void MainWindow::addCommandToInboxStorage(QString type, CommandDetail d){ // inbox: auto inbox = Inbox(inboxPath()); if(inbox.open()){ @@ -10124,7 +10204,7 @@ void MainWindow::addCommandToInbox(CommandDetail d){ v["TEXT"] = QVariant(d.text); } - auto m = Message("UNREAD", "", v); + auto m = Message(type, "", v); inbox.append(m); } } diff --git a/mainwindow.h b/mainwindow.h index 2a6a251..b381943 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -178,6 +178,7 @@ private slots: void on_actionEnable_Spotting_toggled(bool checked); void on_actionEnable_Auto_Reply_toggled(bool checked); void on_menuWindow_aboutToShow(); + void on_actionSetOffset_triggered(); void on_actionShow_Fullscreen_triggered(bool checked); void on_actionShow_Statusbar_triggered(bool checked); void on_actionShow_Frequency_Clock_triggered(bool checked); @@ -951,7 +952,8 @@ private: void processCommandActivity(); QString inboxPath(); void refreshInboxCounts(); - void addCommandToInbox(CommandDetail d); + void addCommandToMyInbox(CommandDetail d); + void addCommandToInboxStorage(QString type, CommandDetail d); void processAlertReplyForCommand(CommandDetail d, QString from, QString cmd); void processSpots(); void processTxQueue(); diff --git a/mainwindow.ui b/mainwindow.ui index ee4525c..136ad88 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -4746,12 +4746,14 @@ list. The list can be maintained in Settings (F2). C&ontrol + + @@ -5636,6 +5638,11 @@ list. The list can be maintained in Settings (F2). Set Frequency... + + + Set Offset... + + diff --git a/varicode.cpp b/varicode.cpp index 2a04176..07edb9f 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -69,10 +69,12 @@ QMap directed_cmds = { {" HB", -1 }, // this is my heartbeat (unused except for faux processing of HBs as directed commands) - // {" ", 10 }, // unused - // {" ", 11 }, // unused + {" MSG TO:", 10 }, // store message at a station + + {" QUERY", 11 }, // generic query + + {" QUERY MSGS", 12 }, // do you have any stored messages? - {" QUERY", 12 }, // issue a generic query {" QUERY CALL", 13 }, // can you transmit a ping to callsign? {" APRS:", 14 }, // send an aprs packet @@ -99,13 +101,13 @@ QMap directed_cmds = { }; // commands allowed to be processed -QSet 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 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 -QSet autoreply_cmds = {0, 1, 2, 3, 4, 6, 12, 13, 30}; +QSet autoreply_cmds = {0, 1, 2, 3, 4, 6, 10, 12, 13, 30}; // commands that should be buffered -QSet buffered_cmds = {3, 5, /*6,*/ /*7,*/ 12, 13, 14, 15}; +QSet buffered_cmds = {3, 5, /*6,*/ /*7,*/ 10, 11, 12, 13, 14, 15}; // commands that may include an SNR value QSet snr_cmds = {25, 29}; @@ -113,6 +115,8 @@ QSet snr_cmds = {25, 29}; // commands that are checksummed and their crc size QMap checksum_cmds = { { 5, 16 }, + { 10, 16 }, + { 11, 16 }, { 12, 16 }, { 13, 16 }, { 14, 16 }, @@ -120,7 +124,7 @@ QMap checksum_cmds = { }; QString callsign_pattern = QString("(?[@]?[A-Z0-9/]+)"); -QString optional_cmd_pattern = QString("(?\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|HEARING[?]|(?:(?:STATUS|HEARING|QUERY CALL|QUERY|ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|TU)(?=[ ]|$))|[?> ]))?"); +QString optional_cmd_pattern = QString("(?\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|MSG TO[:]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|HEARING[?]|(?:(?:STATUS|HEARING|QUERY CALL|QUERY MSGS|QUERY|ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|TU)(?=[ ]|$))|[?> ]))?"); QString optional_grid_pattern = QString("(?\\s?[A-R]{2}[0-9]{2})?"); QString optional_extended_grid_pattern = QString("^(?\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?"); QString optional_num_pattern = QString("(?(?<=SNR|ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?"); @@ -199,6 +203,7 @@ quint16 nmaxgrid = (1<<15)-1; QMap basecalls = { { "<....>", nbasecall + 1 }, // incomplete callsign { "@ALLCALL", nbasecall + 2 }, // ALLCALL group + { "@JS8NET", nbasecall + 3 }, // JS8NET group }; QMap cqs = {