From dfdf23315b0c70c8e56d154cd481ed58cdb2c832 Mon Sep 17 00:00:00 2001 From: Jordan Sherer Date: Thu, 6 Sep 2018 15:22:24 -0400 Subject: [PATCH] Added ability to send CQ QRP/CQ DX/CQ TEST along with customization for the message that the CQ button sends --- Configuration.cpp | 22 ++++++++++++++++++- Configuration.hpp | 3 ++- Configuration.ui | 28 ++++++++++++++++++------ decodedtext.cpp | 8 ++++--- mainwindow.cpp | 17 +++++++++------ varicode.cpp | 54 +++++++++++++++++++++++++++++++++++------------ varicode.h | 9 ++++---- 7 files changed, 105 insertions(+), 36 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index c0f9f60..f1699f6 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -454,6 +454,7 @@ private: Q_SLOT void on_PTT_method_button_group_buttonClicked (int); Q_SLOT void on_station_message_line_edit_textChanged(QString const&); Q_SLOT void on_qth_message_line_edit_textChanged(QString const&); + Q_SLOT void on_cq_message_line_edit_textChanged(QString const&); Q_SLOT void on_reply_message_line_edit_textChanged(QString const&); Q_SLOT void on_add_macro_line_edit_editingFinished (); Q_SLOT void delete_macro (); @@ -556,6 +557,7 @@ private: QString my_grid_; QString my_station_; QString my_qth_; + QString cq_; QString reply_; int callsign_aging_; int activity_aging_; @@ -877,7 +879,12 @@ QString Configuration::my_qth() const return m_->my_qth_; } -QString Configuration::reply() const +QString Configuration::cq_message() const +{ + return m_->cq_; +} + +QString Configuration::reply_message() const { return m_->reply_; } @@ -1043,6 +1050,7 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory, ui_->station_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); ui_->qth_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); ui_->reply_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); + ui_->cq_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this}); ui_->udp_server_port_spin_box->setMinimum (1); ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits::max ()); @@ -1233,6 +1241,7 @@ void Configuration::impl::initialize_models () ui_->activity_aging_spin_box->setValue(activity_aging_); ui_->station_message_line_edit->setText (my_station_.toUpper()); ui_->qth_message_line_edit->setText (my_qth_.toUpper()); + ui_->cq_message_line_edit->setText(cq_.toUpper()); ui_->reply_message_line_edit->setText (reply_.toUpper()); ui_->use_dynamic_grid->setChecked(use_dynamic_info_); ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name())); @@ -1365,6 +1374,7 @@ void Configuration::impl::read_settings () callsign_aging_ = settings_->value ("CallsignAging", 0).toInt (); activity_aging_ = settings_->value ("ActivityAging", 2).toInt (); my_qth_ = settings_->value("MyQTH", QString {}).toString(); + cq_ = settings_->value("CQMessage", QString {"CQCQCQ"}).toString(); reply_ = settings_->value("Reply", QString {"HW CPY?"}).toString(); next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString(); next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString(); @@ -1561,6 +1571,7 @@ void Configuration::impl::write_settings () settings_->setValue ("MyGrid", my_grid_); settings_->setValue ("MyStation", my_station_); settings_->setValue ("MyQTH", my_qth_); + settings_->setValue ("CQMessage", cq_); settings_->setValue ("Reply", reply_); settings_->setValue ("CallsignAging", callsign_aging_); settings_->setValue ("ActivityAging", activity_aging_); @@ -2025,6 +2036,7 @@ void Configuration::impl::accept () my_callsign_ = ui_->callsign_line_edit->text (); my_grid_ = ui_->grid_line_edit->text (); my_station_ = ui_->station_message_line_edit->text().toUpper(); + cq_ = ui_->cq_message_line_edit->text().toUpper(); reply_ = ui_->reply_message_line_edit->text().toUpper(); my_qth_ = ui_->qth_message_line_edit->text().toUpper(); callsign_aging_ = ui_->callsign_aging_spin_box->value(); @@ -2341,6 +2353,14 @@ void Configuration::impl::on_qth_message_line_edit_textChanged(QString const &te } } +void Configuration::impl::on_cq_message_line_edit_textChanged(QString const &text) +{ + QString upper = text.toUpper(); + if(text != upper){ + ui_->cq_message_line_edit->setText (upper); + } +} + void Configuration::impl::on_reply_message_line_edit_textChanged(QString const &text) { QString upper = text.toUpper(); diff --git a/Configuration.hpp b/Configuration.hpp index a904f9c..6033082 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -101,7 +101,8 @@ public: int activity_aging() const; int callsign_aging() const; QString my_qth () const; - QString reply () const; + QString cq_message () const; + QString reply_message () const; QFont text_font () const; QFont decoded_text_font () const; qint32 id_interval () const; diff --git a/Configuration.ui b/Configuration.ui index 2e58ed9..670c232 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -175,21 +175,21 @@ 0 - + Reply Message: - + HW CPY? - + <html><head/><body><p>Station location message</p></body></html> @@ -199,14 +199,14 @@ - + <html><head/><body><p>Station location message that is transmitted in response to &quot;@&quot; directed queries.</p></body></html> - + <html><head/><body><p>Station Description Message</p></body></html> @@ -216,13 +216,27 @@ - + <html><head/><body><p>Station message that is transmitted in response to &quot;&amp;&quot; directed queries.</p></body></html> + + + + CQ Message: + + + + + + + CQCQCQ + + + @@ -2625,7 +2639,7 @@ Right click for insert and delete options. - CQ and BEACON + CQ diff --git a/decodedtext.cpp b/decodedtext.cpp index 2e0cc61..9bed550 100644 --- a/decodedtext.cpp +++ b/decodedtext.cpp @@ -108,7 +108,8 @@ bool DecodedText::tryUnpackBeacon(){ bool isAlt = false; quint8 type = Varicode::FrameUnknown; - QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt); + quint8 bits3 = 0; + QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt, &bits3); if(parts.isEmpty() || parts.length() < 2){ return false; @@ -130,7 +131,7 @@ bool DecodedText::tryUnpackBeacon(){ cmp.append(parts.at(1)); } compound_ = cmp.join("/"); - message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? "CQCQCQ" : "BEACON").arg(extra_); + message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "BEACON").arg(extra_); frameType_ = type; return true; } @@ -143,7 +144,8 @@ bool DecodedText::tryUnpackCompound(){ } quint8 type = Varicode::FrameUnknown; - auto parts = Varicode::unpackCompoundMessage(m, &type); + quint8 bits3 = 0; + auto parts = Varicode::unpackCompoundMessage(m, &type, &bits3); if(parts.isEmpty() || parts.length() < 2){ return false; } diff --git a/mainwindow.cpp b/mainwindow.cpp index c9d5ca9..c6d1db1 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -6161,6 +6161,7 @@ QStringList MainWindow::buildFT8MessageFrames(QString const& text){ bool lineStartsWithBaseCall = ( line.startsWith("ALLCALL") || line.startsWith("CQCQCQ") || + line.startsWith("CQ ") || line.startsWith("BEACON") ); @@ -7308,9 +7309,13 @@ void MainWindow::on_clearAction_triggered(QObject * sender){ } void MainWindow::on_cqMacroButton_clicked(){ - QString mygrid = m_config.my_grid().left(4); - QString text = QString("CQCQCQ %1").arg(mygrid).trimmed(); - addMessageText(text); + auto message = m_config.cq_message(); + if(message.isEmpty()){ + QString mygrid = m_config.my_grid().left(4); + message = QString("CQCQCQ %1").arg(mygrid).trimmed(); + } + + addMessageText(message); } void MainWindow::on_replyMacroButton_clicked(){ @@ -7318,7 +7323,7 @@ void MainWindow::on_replyMacroButton_clicked(){ if(call.isEmpty()){ return; } - addMessageText(QString("%1 %2").arg(call).arg(m_config.reply())); + addMessageText(QString("%1 %2").arg(call).arg(m_config.reply_message())); } void MainWindow::on_qthMacroButton_clicked(){ @@ -7410,7 +7415,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){ return; } - addMessageText(QString("%1 %2").arg(selectedCall).arg(m_config.reply()), true); + addMessageText(QString("%1 %2").arg(selectedCall).arg(m_config.reply_message()), true); }); auto sendSNRAction = menu->addAction(QString("%1 SNR - Send a signal report to the selected callsign").arg(call).trimmed()); @@ -9719,7 +9724,7 @@ void MainWindow::displayBandActivity() { textItem->setTextAlignment(flag); if (text.last().contains(QRegularExpression { - "\\b(CQCQCQ|BEACON)\\b" + "\\b(CQCQCQ|CQ)\\b" })) { offsetItem->setBackground(QBrush(m_config.color_CQ())); ageItem->setBackground(QBrush(m_config.color_CQ())); diff --git a/varicode.cpp b/varicode.cpp index 10a2749..14366ee 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -102,7 +102,7 @@ QRegularExpression directed_re("^" + optional_cmd_pattern + optional_num_pattern); -QRegularExpression beacon_re(R"(^\s*(?CQCQCQ|BEACON)(?:\s(?[A-R]{2}[0-9]{2}))?\b)"); +QRegularExpression beacon_re(R"(^\s*(?CQCQCQ|CQ QRP|CQ DX|CQ TEST|BEACON)(?:\s(?[A-R]{2}[0-9]{2}))?\b)"); QRegularExpression compound_re("^\\s*[<]" + callsign_pattern + @@ -346,6 +346,13 @@ QMap basecalls = { { "ALLCALL", nbasecall + 2 }, }; +QMap cqs = { + { 0, "CQCQCQ" }, + { 1, "CQ DX" }, + { 2, "CQ QRP" }, + { 3, "CQ TEST" }, +}; + QMap dbm2mw = { {0 , 1}, // 1mW {3 , 2}, // 2mW @@ -429,6 +436,13 @@ int dbmTomwatts(int dbm){ * VARICODE */ +QString Varicode::cqString(int number){ + if(!cqs.contains(number)){ + return QString{}; + } + return cqs[number]; +} + QString Varicode::formatSNR(int snr){ if(snr < -60 || snr > 60){ return QString(); @@ -1094,6 +1108,8 @@ int Varicode::isCommandChecksumed(const QString &cmd){ } // CQCQCQ EM73 +// CQ DX EM73 +// CQ QRP EM73 // BEACON EM73 QString Varicode::packBeaconMessage(QString const &text, const QString &callsign, int *n){ QString frame; @@ -1141,8 +1157,9 @@ QString Varicode::packBeaconMessage(QString const &text, const QString &callsign packed_extra |= (1<<15); } + quint8 cqNumber = cqs.key(type, 0); - frame = packCompoundFrame(base, fix, isPrefix, FrameBeacon, packed_extra); + frame = packCompoundFrame(base, fix, isPrefix, FrameBeacon, packed_extra, cqNumber); if(frame.isEmpty()){ if(n) *n = 0; return frame; @@ -1152,11 +1169,12 @@ QString Varicode::packBeaconMessage(QString const &text, const QString &callsign return frame; } -QStringList Varicode::unpackBeaconMessage(const QString &text, quint8 *pType, bool * isAlt){ +QStringList Varicode::unpackBeaconMessage(const QString &text, quint8 *pType, bool * isAlt, quint8 * pBits3){ quint8 type = FrameBeacon; quint16 num = nmaxgrid; + quint8 bits3 = 0; - QStringList unpacked = unpackCompoundFrame(text, &type, &num); + QStringList unpacked = unpackCompoundFrame(text, &type, &num, &bits3); if(unpacked.isEmpty() || type != FrameBeacon){ return QStringList{}; } @@ -1165,6 +1183,7 @@ QStringList Varicode::unpackBeaconMessage(const QString &text, quint8 *pType, bo if(isAlt) *isAlt = (num & (1<<15)); if(pType) *pType = type; + if(pBits3) *pBits3 = bits3; return unpacked; } @@ -1229,17 +1248,18 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){ extra = Varicode::packGrid(grid); } - frame = Varicode::packCompoundFrame(base, fix, isPrefix, type, extra); + frame = Varicode::packCompoundFrame(base, fix, isPrefix, type, extra, 0); if(n) *n = parsedText.captured(0).length(); return frame; } -QStringList Varicode::unpackCompoundMessage(const QString &text, quint8 *pType){ +QStringList Varicode::unpackCompoundMessage(const QString &text, quint8 *pType, quint8 *pBits3){ quint8 type = FrameCompound; quint16 extra = nmaxgrid; + quint8 bits3 = 0; - QStringList unpacked = unpackCompoundFrame(text, &type, &extra); + QStringList unpacked = unpackCompoundFrame(text, &type, &extra, &bits3); if(unpacked.isEmpty() || (type != FrameCompound && type != FrameCompoundDirected)){ return QStringList {}; } @@ -1258,11 +1278,12 @@ QStringList Varicode::unpackCompoundMessage(const QString &text, quint8 *pType){ } if(pType) *pType = type; + if(pBits3) *pBits3 = bits3; return unpacked; } -QString Varicode::packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint8 type, quint16 num){ +QString Varicode::packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint8 type, quint16 num, quint8 bits3){ QString frame; // needs to be a compound type... @@ -1283,8 +1304,9 @@ QString Varicode::packCompoundFrame(const QString &baseCallsign, const QString & quint16 packed_11 = (num & mask11) >> 5; quint8 packed_5 = num & mask5; + quint8 packed_8 = (packed_5 << 3) | bits3; - // [3][28][22][11],[3][5] = 72 + // [3][28][22][11],[5][3] = 72 auto bits = ( Varicode::intToBits(packed_flag, 3) + Varicode::intToBits(packed_base, 28) + @@ -1292,19 +1314,22 @@ QString Varicode::packCompoundFrame(const QString &baseCallsign, const QString & Varicode::intToBits(packed_11, 11) ); - return Varicode::pack72bits(Varicode::bitsToInt(bits), packed_5 % 32); + return Varicode::pack72bits(Varicode::bitsToInt(bits), packed_8); } -QStringList Varicode::unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum){ +QStringList Varicode::unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum, quint8 *pBits3){ QStringList unpacked; if(text.length() < 12 || text.contains(" ")){ return unpacked; } - // [3][28][22][11],[3][5] = 72 - quint8 packed_5 = 0; - auto bits = Varicode::intToBits(Varicode::unpack72bits(text, &packed_5), 64); + // [3][28][22][11],[5][3] = 72 + quint8 packed_8 = 0; + auto bits = Varicode::intToBits(Varicode::unpack72bits(text, &packed_8), 64); + + quint8 packed_5 = packed_8 >> 3; + quint8 packed_3 = packed_8 & ((1<<3)-1); quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3)); @@ -1326,6 +1351,7 @@ QStringList Varicode::unpackCompoundFrame(const QString &text, quint8 *pType, qu if(pType) *pType = packed_flag; if(pNum) *pNum = num; + if(pBits3) *pBits3 = packed_3; if(isPrefix){ unpacked.append(fix); diff --git a/varicode.h b/varicode.h index 8196bec..83b4d8d 100644 --- a/varicode.h +++ b/varicode.h @@ -56,6 +56,7 @@ public: //Varicode(); + static QString cqString(int number); static QString formatSNR(int snr); static QString formatPWR(int dbm); @@ -124,13 +125,13 @@ public: static int isCommandChecksumed(const QString &cmd); static QString packBeaconMessage(QString const &text, QString const&callsign, int *n); - static QStringList unpackBeaconMessage(const QString &text, quint8 *pType, bool *isAlt); + static QStringList unpackBeaconMessage(const QString &text, quint8 *pType, bool *isAlt, quint8 *pBits3); static QString packCompoundMessage(QString const &text, int *n); - static QStringList unpackCompoundMessage(const QString &text, quint8 *pType); + static QStringList unpackCompoundMessage(const QString &text, quint8 *pType, quint8 *pBits3); - static QString packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint8 type, quint16 num); - static QStringList unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum); + static QString packCompoundFrame(const QString &baseCallsign, const QString &fix, bool isPrefix, quint8 type, quint16 num, quint8 bits3); + static QStringList unpackCompoundFrame(const QString &text, quint8 *pType, quint16 *pNum, quint8 *pBits3); static QString packDirectedMessage(QString const& text, QString const& callsign, QString *pTo, QString * pCmd, QString *pNum, int *n); static QStringList unpackDirectedMessage(QString const& text, quint8 *pType);