diff --git a/decodedtext.cpp b/decodedtext.cpp index 0d572d0..2e0cc61 100644 --- a/decodedtext.cpp +++ b/decodedtext.cpp @@ -161,7 +161,7 @@ bool DecodedText::tryUnpackCompound(){ if(type == Varicode::FrameCompound){ message_ = QString("%1: ").arg(compound_); } else if(type == Varicode::FrameCompoundDirected){ - message_ = QString("%1%2").arg(compound_).arg(extra_); + message_ = QString("%1%2 ").arg(compound_).arg(extra_); directed_ = QStringList{ "<....>", compound_ } + parts.mid(2); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 2f4514c..6c79c31 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3247,6 +3247,12 @@ void MainWindow::readFromStdout() //readFromStdout m_bandActivity[offset].append(d); m_rxActivityQueue.append(d); + // if we have any "first" frame, and a buffer is already established, clear it... + if(d.bits == Varicode::FT8CallFirst && m_messageBuffer.contains(d.freq/10*10)){ + qDebug() << "first message encountered, clearing existing buffer" << (d.freq/10*10); + m_messageBuffer.remove(d.freq/10*10); + } + // if we have a data frame, and a message buffer has been established, buffer it... if(m_messageBuffer.contains(d.freq/10*10) && !decodedtext.isCompound() && !decodedtext.isDirectedMessage()){ qDebug() << "buffering data" << (d.freq/10*10) << d.text; @@ -5771,6 +5777,8 @@ QStringList MainWindow::buildFT8MessageFrames(QString const& text){ line = lstrip(line.mid(basecall.length() + 1)); } +#define ALLOW_SEND_COMPOUND 1 + while(line.size() > 0){ QString frame; @@ -6006,6 +6014,9 @@ bool MainWindow::prepareNextMessageFrame() int sent = count - m_txFrameQueue.count(); m_i3bit = Varicode::FT8Call; + if(sent == 1){ + m_i3bit = Varicode::FT8CallFirst; + } if(count == sent){ m_i3bit = Varicode::FT8CallLast; } @@ -6019,30 +6030,6 @@ bool MainWindow::prepareNextMessageFrame() return true; } - - - /* - QString txt = ui->extFreeTextMsg->toPlainText().trimmed().mid(m_extFreeTxtPos).trimmed(); - - QString nextTxt = parseFT8Message(txt); - ui->nextFreeTextMsg->setText(nextTxt); - QRegExp n = QRegExp("^" + QRegExp::escape(nextTxt)); - - ui->extFreeTextMsg->setPlainText(txt.remove(n).trimmed()); - */ - - /* - if(txt.contains(n)){ - QTextCursor tc = ui->extFreeTextMsg->textCursor(); - tc.setPosition(0); - m_extFreeTxtPos += n.matchedLength(); - tc.setPosition(m_extFreeTxtPos, QTextCursor::KeepAnchor); - QTextCharFormat cf = tc.charFormat(); - cf.setFontStrikeOut(true); - tc.mergeCharFormat(cf);call - } - */ - } bool MainWindow::isFreqOffsetFree(int f, int bw){ @@ -8737,7 +8724,7 @@ void MainWindow::processCompoundActivity() { } // if we don't have an initialized command, skip... - if (buffer.cmd.bits != Varicode::FT8Call && buffer.cmd.bits != Varicode::FT8CallLast) { + if (buffer.cmd.bits != Varicode::FT8Call && buffer.cmd.bits != Varicode::FT8CallFirst && buffer.cmd.bits != Varicode::FT8CallLast) { qDebug() << "-> buffer.cmd bits is invalid...skip"; continue; } @@ -8799,7 +8786,7 @@ void MainWindow::processBufferedActivity() { continue; } - if (buffer.msgs.last().bits == Varicode::FT8Call) { + if (buffer.msgs.last().bits != Varicode::FT8CallLast) { continue; } @@ -8919,10 +8906,6 @@ void MainWindow::processCommandActivity() { if (d.cmd == "?") { reply = QString("%1 SNR %2").arg(d.from).arg(Varicode::formatSNR(d.snr)); } - // QUERIED ACK - //else if(d.cmd == "^"){ - // reply = QString("%1 ACK").arg(Radio::base_callsign(d.from)); - //} // QUERIED PWR else if (d.cmd == "%" && !isAllCall && m_config.my_dBm() >= 0) { reply = QString("%1 PWR %2").arg(d.from).arg(Varicode::formatPWR(m_config.my_dBm())); @@ -8966,18 +8949,13 @@ void MainWindow::processCommandActivity() { auto d = m_callActivity[call]; - lines.append(QString("%1 %2").arg(d.call).arg(Varicode::formatSNR(d.snr))); + lines.append(QString("<%1 SNR %2>").arg(d.call).arg(Varicode::formatSNR(d.snr))); i++; } - lines.prepend(QString("%1 ACK %2\n").arg(d.from).arg(i)); - reply = lines.join(' '); - } - // PROCESS MESSAGE ACK - else if (d.cmd == "^" && !isAllCall) { - // TODO: jsherer - perhaps parse d.text and ensure it is a valid message as well as prefix it with our call... - reply = QString("%1 ACK").arg(d.from); + lines.prepend(QString("<%1 HEARING>").arg(m_config.my_callsign())); + reply = lines.join('\n'); } // PROCESS RETRANSMIT else if (d.cmd == "|" && !isAllCall) { diff --git a/varicode.cpp b/varicode.cpp index 2422f30..65ff350 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -43,8 +43,8 @@ QMap directed_cmds = { {"@", 1 }, // query qth {"&", 2 }, // query station message {"$", 3 }, // query station(s) heard - // {"^", 4 }, // query ack {"%", 5 }, // query pwr + // 4. {"|", 6 }, // retransmit message {"!", 7 }, // alert message {"#", 8 }, // all or nothing message @@ -53,28 +53,29 @@ QMap directed_cmds = { // {"/", 10 }, // unused? (can we even use stroke?) // directed responses - {" RR", 21 }, // roger roger (not visible in UI but still exists) - {" QSL?", 22 }, // do you copy? - {" QSL", 23 }, // i copy - {" PWR", 24 }, // power level - {" 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 + {" HEARING", 20 }, // i am hearing the following stations + {" RR", 21 }, // roger roger (not visible in UI but still exists) + {" QSL?", 22 }, // do you copy? + {" QSL", 23 }, // i copy + {" PWR", 24 }, // power level + {" 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 }; -QSet allowed_cmds = {0, 1, 2, 3, 4, 5, 6, 7, 8, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; +QSet allowed_cmds = {0, 1, 2, 3, /*4,*/ 5, 6, 7, 8, /*...*/ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; QSet buffered_cmds = {6, 7, 8}; QString callsign_pattern = QString("(?[A-Z0-9/]+)"); -QString optional_cmd_pattern = QString("(?\\s?(?:AGN[?]|QSL[?]?|ACK|RR|73|YES|NO|SNR|PWR|[?@&$^%|!# ]))?"); +QString optional_cmd_pattern = QString("(?\\s?(?:AGN[?]|ACK|73|YES|NO|SNR|PWR|QSL[?]?|RR|HEARING|[?@&$%|!# ]))?"); QString optional_grid_pattern = QString("(?\\s?[A-R]{2}[0-9]{2})?"); QString optional_pwr_pattern = QString("(?(?<=PWR)\\s?\\d+\\s?[KM]?W)?"); -QString optional_num_pattern = QString("(?(?<=SNR)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?"); +QString optional_num_pattern = QString("(?(?<=SNR|HEARING)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?"); QRegularExpression directed_re("^" + callsign_pattern + @@ -91,8 +92,7 @@ QRegularExpression compound_re("^[<]" + optional_cmd_pattern + optional_pwr_pattern + optional_num_pattern + - ")" + - "[>]"); + ")[>]"); QMap hufftable = { // char code weight diff --git a/varicode.h b/varicode.h index 26d86c8..fb7da4a 100644 --- a/varicode.h +++ b/varicode.h @@ -19,8 +19,8 @@ public: FT8 = 0, // [000] FT8Fox = 1, // [001] FT8Call = 2, // [010] - FT8CallLast = 3, // [011] <- used to indicate last frame in transmission - FT8CallReservedA = 4, // [100] + FT8CallLast = 3, // [011] <- used to indicate the last frame in a transmission + FT8CallFirst = 4, // [100] <- used to indicate the first frmae in a transmission FT8CallReservedB = 5, // [101] FT8CallReservedC = 6, // [110] FT8CallReservedD = 7, // [111]