From 12299957d738559459ceb7e171d8acff621519f0 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 30 Dec 2018 12:35:41 +0000 Subject: [PATCH 1/4] Add Fox log ADIF export to the Fox Log window log table contextual pop up menu --- models/FoxLog.cpp | 71 ++++++++++++++++++++++++++++++++++++++-- models/FoxLog.hpp | 5 ++- widgets/FoxLogWindow.cpp | 45 ++++++++++++++++++++----- widgets/FoxLogWindow.hpp | 4 +-- widgets/mainwindow.cpp | 8 ++--- 5 files changed, 114 insertions(+), 19 deletions(-) diff --git a/models/FoxLog.cpp b/models/FoxLog.cpp index 1f985f620..504ddd2a8 100644 --- a/models/FoxLog.cpp +++ b/models/FoxLog.cpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include "Configuration.hpp" #include "qt_db_helpers.hpp" #include "pimpl_impl.hpp" @@ -17,12 +19,15 @@ class FoxLog::impl final : public QSqlTableModel { public: - impl (); + impl (Configuration const * configuration); + Configuration const * configuration_; QSqlQuery mutable dupe_query_; + QSqlQuery mutable export_query_; }; -FoxLog::impl::impl () +FoxLog::impl::impl (Configuration const * configuration) + : configuration_ {configuration} { if (!database ().tables ().contains ("fox_log")) { @@ -43,6 +48,9 @@ FoxLog::impl::impl () SQL_error_check (dupe_query_, &QSqlQuery::prepare, "SELECT COUNT(*) FROM fox_log WHERE call = :call AND band = :band"); + SQL_error_check (export_query_, &QSqlQuery::prepare, + "SELECT band, \"when\", call, grid, report_sent, report_rcvd FROM fox_log ORDER BY \"when\""); + setEditStrategy (QSqlTableModel::OnFieldChange); setTable ("fox_log"); setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)")); @@ -60,7 +68,8 @@ FoxLog::impl::impl () SQL_error_check (*this, &QSqlTableModel::select); } -FoxLog::FoxLog () +FoxLog::FoxLog (Configuration const * configuration) + : m_ {configuration} { } @@ -142,3 +151,59 @@ void FoxLog::reset () m_->setEditStrategy (QSqlTableModel::OnFieldChange); } } + +namespace +{ + struct ADIF_field + { + explicit ADIF_field (QString const& name, QString const& value) + : name_ {name} + , value_ {value} + { + } + + QString name_; + QString value_; + }; + + QTextStream& operator << (QTextStream& os, ADIF_field const& field) + { + if (field.value_.size ()) + { + os << QString {"<%1:%2>%3 "}.arg (field.name_).arg (field.value_.size ()).arg (field.value_); + } + return os; + } +} + +void FoxLog::export_qsos (QTextStream& out) const +{ + out << "WSJT-X FT8 DXpedition Mode Fox Log\n"; + + SQL_error_check (m_->export_query_, static_cast (&QSqlQuery::exec)); + auto record = m_->export_query_.record (); + auto band_index = record.indexOf ("band"); + auto when_index = record.indexOf ("when"); + auto call_index = record.indexOf ("call"); + auto grid_index = record.indexOf ("grid"); + auto sent_index = record.indexOf ("report_sent"); + auto rcvd_index = record.indexOf ("report_rcvd"); + while (m_->export_query_.next ()) + { + auto when = QDateTime::fromMSecsSinceEpoch (m_->export_query_.value (when_index).toULongLong () * 1000ull, Qt::UTC); + out << '\n' + << ADIF_field {"band", m_->export_query_.value (band_index).toString ()} + << ADIF_field {"mode", "FT8"} + << ADIF_field {"qso_date", when.toString ("yyyyMMdd")} + << ADIF_field {"time_on", when.toString ("hhmmss")} + << ADIF_field {"call", m_->export_query_.value (call_index).toString ()} + << ADIF_field {"gridsquare", m_->export_query_.value (grid_index).toString ()} + << ADIF_field {"rst_sent", m_->export_query_.value (sent_index).toString ()} + << ADIF_field {"rst_rcvd", m_->export_query_.value (rcvd_index).toString ()} + << ADIF_field {"station_callsign", m_->configuration_->my_callsign ()} + << ADIF_field {"my_gridsquare", m_->configuration_->my_grid ()} + << ADIF_field {"operator", m_->configuration_->opCall ()} + << ""; + } + out << endl; +} diff --git a/models/FoxLog.hpp b/models/FoxLog.hpp index caa8e358f..9af0b2543 100644 --- a/models/FoxLog.hpp +++ b/models/FoxLog.hpp @@ -7,12 +7,14 @@ class QDateTime; class QString; class QSqlTableModel; +class QTextStream; +class Configuration; class FoxLog final : private boost::noncopyable { public: - explicit FoxLog (); + explicit FoxLog (Configuration const *); ~FoxLog (); // returns false if insert fails, dupe call+band @@ -23,6 +25,7 @@ public: QSqlTableModel * model (); void reset (); + void export_qsos (QTextStream&) const; private: class impl; diff --git a/widgets/FoxLogWindow.cpp b/widgets/FoxLogWindow.cpp index 4b8fbc253..36f20b85b 100644 --- a/widgets/FoxLogWindow.cpp +++ b/widgets/FoxLogWindow.cpp @@ -1,15 +1,17 @@ #include "FoxLogWindow.hpp" #include -#include #include #include #include +#include +#include #include "SettingsGroup.hpp" #include "Configuration.hpp" #include "MessageBox.hpp" #include "models/Bands.hpp" +#include "models/FoxLog.hpp" #include "item_delegates/ForeignKeyDelegate.hpp" #include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp" #include "item_delegates/CallsignDelegate.hpp" @@ -22,23 +24,23 @@ class FoxLogWindow::impl final { public: - explicit impl (QSqlTableModel * log_model) - : log_model_ {log_model} + explicit impl (FoxLog * log) + : log_ {log} { } - QSqlTableModel * log_model_; + FoxLog * log_; Ui::FoxLogWindow ui_; }; FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configuration - , QSqlTableModel * fox_log_model, QWidget * parent) + , FoxLog * fox_log, QWidget * parent) : AbstractLogWindow {"Fox Log Window", settings, configuration, parent} - , m_ {fox_log_model} + , m_ {fox_log} { setWindowTitle (QApplication::applicationName () + " - Fox Log"); m_->ui_.setupUi (this); - m_->ui_.log_table_view->setModel (m_->log_model_); + m_->ui_.log_table_view->setModel (m_->log_->model ()); set_log_view (m_->ui_.log_table_view); m_->ui_.log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this}); @@ -50,6 +52,31 @@ FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configur m_->ui_.callers_label->setNum (0); // actions + auto export_action = new QAction {tr ("&Export ADIF ..."), m_->ui_.log_table_view}; + m_->ui_.log_table_view->insertAction (nullptr, export_action); + connect (export_action, &QAction::triggered, [this, configuration] (bool /*checked*/) { + auto file_name = QFileDialog::getSaveFileName (this + , tr ("Export ADIF Log File") + , configuration->writeable_data_dir ().absolutePath () + , tr ("ADIF Log (*.adi)")); + if (file_name.size () && m_->log_) + { + QFile ADIF_file {file_name}; + if (ADIF_file.open (QIODevice::WriteOnly | QIODevice::Text)) + { + QTextStream output_stream {&ADIF_file}; + m_->log_->export_qsos (output_stream); + } + else + { + MessageBox::warning_message (this + , tr ("Export ADIF File Error") + , tr ("Cannot open \"%1\" for writing: %2") + .arg (ADIF_file.fileName ()).arg (ADIF_file.errorString ())); + } + } + }); + auto reset_action = new QAction {tr ("&Reset ..."), m_->ui_.log_table_view}; m_->ui_.log_table_view->insertAction (nullptr, reset_action); connect (reset_action, &QAction::triggered, [this, configuration] (bool /*checked*/) { @@ -88,10 +115,10 @@ void FoxLogWindow::log_model_changed (int row) { if (row >= 0) { - m_->log_model_->selectRow (row); + m_->log_->model ()->selectRow (row); } else { - m_->log_model_->select (); + m_->log_->model ()->select (); } } diff --git a/widgets/FoxLogWindow.hpp b/widgets/FoxLogWindow.hpp index 65bcb0bd0..c9cc18a40 100644 --- a/widgets/FoxLogWindow.hpp +++ b/widgets/FoxLogWindow.hpp @@ -7,7 +7,7 @@ class QSettings; class Configuration; class QFont; -class QSqlTableModel; +class FoxLog; class FoxLogWindow final : public AbstractLogWindow @@ -15,7 +15,7 @@ class FoxLogWindow final Q_OBJECT public: - explicit FoxLogWindow (QSettings *, Configuration const *, QSqlTableModel * fox_log_model + explicit FoxLogWindow (QSettings *, Configuration const *, FoxLog * fox_log , QWidget * parent = nullptr); ~FoxLogWindow (); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index bb0089d95..51d2fbf2e 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -2453,15 +2453,15 @@ void MainWindow::on_actionAstronomical_data_toggled (bool checked) void MainWindow::on_fox_log_action_triggered() { - if (!m_foxLog) m_foxLog.reset (new FoxLog); + if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config}); if (!m_foxLogWindow) { - m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_foxLog->model ()}); + m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_foxLog.data ()}); // Connect signals from fox log window connect (this, &MainWindow::finished, m_foxLogWindow.data (), &FoxLogWindow::close); connect (m_foxLogWindow.data (), &FoxLogWindow::reset_log_model, [this] () { - if (!m_foxLog) m_foxLog.reset (new FoxLog); + if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config}); m_foxLog->reset (); }); } @@ -8236,7 +8236,7 @@ list2Done: m_hisGrid=m_foxQSO[hc1].grid; m_rptSent=m_foxQSO[hc1].sent; m_rptRcvd=m_foxQSO[hc1].rcvd; - if (!m_foxLog) m_foxLog.reset (new FoxLog); + if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config}); if (!m_foxLogWindow) on_fox_log_action_triggered (); if (m_foxLog->add_QSO (QSO_time, m_hisCall, m_hisGrid, m_rptSent, m_rptRcvd, m_lastBand)) { From 9d0473f1e8d58574679c94c396682270eb42eb3a Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 31 Dec 2018 10:37:36 -0500 Subject: [PATCH 2/4] Include grid in Tx1 messages with , such as " K1JT FN20". --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 259dc1d9f..a80dcf286 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4913,7 +4913,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } if(!bHisCall) { t=t0a; - msgtype(t0a, ui->tx1); + msgtype(t0a + my_grid, ui->tx1); } if(SpecOp::NA_VHF==m_config.special_op_id()) sent=my_grid; if(SpecOp::FIELD_DAY==m_config.special_op_id()) sent=m_config.Field_Day_Exchange(); From 5b0f713cd4656e4064a49120c3aa8650dc6d010d Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 1 Jan 2019 16:19:01 +0000 Subject: [PATCH 3/4] Defer dwonloading LoTW users file until "Settings->Colors->Fetch" button pressed This change also repairs a defect in showing potential LoTW users when the "Settings->General->Show DXCC, grid, and worked before status" option is not checked. --- Configuration.cpp | 4 +--- LotWUsers.cpp | 14 ++++++++++---- widgets/displaytext.cpp | 6 +++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 57978f907..3cc900e57 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -1004,13 +1004,11 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network // this must be done after the default paths above are set read_settings (); - // conditionally load LotW users data - ui_->LotW_CSV_fetch_push_button->setEnabled (false); + // set up LoTW users CSV file fetching connect (&lotw_users_, &LotWUsers::load_finished, [this] () { ui_->LotW_CSV_fetch_push_button->setEnabled (true); }); lotw_users_.set_local_file_path (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv")); - lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text ()); // // validation diff --git a/LotWUsers.cpp b/LotWUsers.cpp index 3876cd7bf..877e70549 100644 --- a/LotWUsers.cpp +++ b/LotWUsers.cpp @@ -1,6 +1,7 @@ #include "LotWUsers.hpp" #include +#include #include #include @@ -265,7 +266,9 @@ void LotWUsers::set_age_constraint (qint64 uploaded_since_days) bool LotWUsers::user (QString const& call) const { - if (m_->future_load_.valid ()) + // check if a pending asynchronous load is ready + if (m_->future_load_.valid () + && std::future_status::ready == m_->future_load_.wait_for (std::chrono::seconds {0})) { try { @@ -278,10 +281,13 @@ bool LotWUsers::user (QString const& call) const } Q_EMIT load_finished (); } - auto p = m_->last_uploaded_.constFind (call); - if (p != m_->last_uploaded_.end ()) + if (m_->last_uploaded_.size ()) { - return p.value ().daysTo (QDate::currentDate ()) <= m_->age_constraint_; + auto p = m_->last_uploaded_.constFind (call); + if (p != m_->last_uploaded_.end ()) + { + return p.value ().daysTo (QDate::currentDate ()) <= m_->age_constraint_; + } } return false; } diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 73df8af63..56e7931be 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -400,7 +400,11 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con } else { - highlight_types types {Highlight::CQ, Highlight::LotW}; + highlight_types types {Highlight::CQ}; + if (m_config && m_config->lotw_users ().user (decodedText.CQersCall())) + { + types.push_back (Highlight::LotW); + } set_colours (m_config, &bg, &fg, types); } } From 6e949fa64d39163612bfb2093ed309bebc136447 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 1 Jan 2019 23:38:14 +0000 Subject: [PATCH 4/4] Debug trace facility for UDP message protocol Build with the CMake configuration WSJT_TRACE_UDP set to ON to enable UDP message tracing to the debug log. --- CMakeLists.txt | 1 + MessageClient.cpp | 33 +++++++++++++++++++++++++++++++++ wsjtx_config.h.in | 1 + 3 files changed, 35 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4ee758b8..2040766e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,7 @@ option (WSJT_SOFT_KEYING "Apply a ramp to CW keying envelope to reduce transient option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation.") option (WSJT_GENERATE_DOCS "Generate documentation files." ON) option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.") +option (WSJT_TRACE_UDP "Debugging option that turns on UDP message protocol diagnostics.") option (WSJT_BUILD_UTILS "Build simulators and code demonstrators." ON) CMAKE_DEPENDENT_OPTION (WSJT_HAMLIB_VERBOSE_TRACE "Debugging option that turns on full Hamlib internal diagnostics." OFF WSJT_HAMLIB_TRACE OFF) diff --git a/MessageClient.cpp b/MessageClient.cpp index 6ceca2dce..d35cc338e 100644 --- a/MessageClient.cpp +++ b/MessageClient.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "NetworkMessage.hpp" @@ -18,6 +19,13 @@ #include "moc_MessageClient.cpp" +// some trace macros +#if WSJT_TRACE_UDP +#define TRACE_UDP(MSG) qDebug () << QString {"MessageClient::%1:"}.arg (__func__) << MSG +#else +#define TRACE_UDP(MSG) +#endif + class MessageClient::impl : public QUdpSocket { @@ -101,6 +109,7 @@ void MessageClient::impl::host_info_results (QHostInfo host_info) if (blocked_addresses_.end () == std::find (blocked_addresses_.begin (), blocked_addresses_.end (), server)) { server_ = server; + TRACE_UDP ("resulting server:" << server); // send initial heartbeat which allows schema negotiation heartbeat (); @@ -129,6 +138,7 @@ void MessageClient::impl::pending_datagrams () port_type sender_port; if (0 <= readDatagram (datagram.data (), datagram.size (), &sender_address, &sender_port)) { + TRACE_UDP ("message received from:" << sender_address << "port:" << sender_port); parse_message (datagram); } } @@ -168,6 +178,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg) quint8 modifiers {0}; in >> time >> snr >> delta_time >> delta_frequency >> mode >> message >> low_confidence >> modifiers; + TRACE_UDP ("Reply: time:" << time << "snr:" << snr << "dt:" << delta_time << "df:" << delta_frequency << "mode:" << mode << "message:" << message << "low confidence:" << low_confidence << "modifiers: 0x" << hex << modifiers); if (check_status (in) != Fail) { Q_EMIT self_->reply (time, snr, delta_time, delta_frequency @@ -178,6 +189,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg) break; case NetworkMessage::Replay: + TRACE_UDP ("Replay"); if (check_status (in) != Fail) { last_message_.clear (); @@ -189,6 +201,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg) { bool auto_only {false}; in >> auto_only; + TRACE_UDP ("Halt Tx auto_only:" << auto_only); if (check_status (in) != Fail) { Q_EMIT self_->halt_tx (auto_only); @@ -201,6 +214,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg) QByteArray message; bool send {true}; in >> message >> send; + TRACE_UDP ("FreeText message:" << message << "send:" << send); if (check_status (in) != Fail) { Q_EMIT self_->free_text (QString::fromUtf8 (message), send); @@ -212,6 +226,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg) { QByteArray location; in >> location; + TRACE_UDP ("Location location:" << location); if (check_status (in) != Fail) { Q_EMIT self_->location (QString::fromUtf8 (location)); @@ -226,6 +241,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg) QColor fg; // default invalid color bool last_only {false}; in >> call >> bg >> fg >> last_only; + TRACE_UDP ("HighlightCallsign call:" << call << "bg:" << bg << "fg:" << fg); if (check_status (in) != Fail && call.size ()) { Q_EMIT self_->highlight_callsign (QString::fromUtf8 (call), bg, fg, last_only); @@ -240,9 +256,17 @@ void MessageClient::impl::parse_message (QByteArray const& msg) // parsed here they are still partially parsed in the // message reader class to negotiate the maximum schema // number being used on the network. + if (NetworkMessage::Heartbeat != in.type ()) + { + TRACE_UDP ("ignoring message type:" << in.type ()); + } break; } } + else + { + TRACE_UDP ("ignored message for id:" << in.id ()); + } } catch (std::exception const& e) { @@ -264,6 +288,7 @@ void MessageClient::impl::heartbeat () << version_.toUtf8 () << revision_.toUtf8 (); if (OK == check_status (hb)) { + TRACE_UDP ("schema:" << schema_ << "max schema:" << NetworkMessage::Builder::schema_number << "version:" << version_ << "revision:" << revision_); writeDatagram (message, server_, server_port_); } } @@ -277,6 +302,7 @@ void MessageClient::impl::closedown () NetworkMessage::Builder out {&message, NetworkMessage::Close, id_, schema_}; if (OK == check_status (out)) { + TRACE_UDP (""); writeDatagram (message, server_, server_port_); } } @@ -369,6 +395,7 @@ void MessageClient::set_server (QString const& server) if (!server.isEmpty ()) { // queue a host address lookup + TRACE_UDP ("server host DNS lookup:" << server); QHostInfo::lookupHost (server, &*m_, SLOT (host_info_results (QHostInfo))); } } @@ -415,6 +442,7 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con << tx_enabled << transmitting << decoding << rx_df << tx_df << de_call.toUtf8 () << de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 () << fast_mode << special_op_mode; + TRACE_UDP ("frequency:" << f << "mode:" << mode << "DX:" << dx_call << "report:" << report << "Tx mode:" << tx_mode << "tx_enabled:" << tx_enabled << "Tx:" << transmitting << "decoding:" << decoding << "Rx df:" << rx_df << "Tx df:" << tx_df << "DE:" << de_call << "DE grid:" << de_grid << "DX grid:" << dx_grid << "w/d t/o:" << watchdog_timeout << "sub_mode:" << sub_mode << "fast mode:" << fast_mode << "spec op mode:" << special_op_mode); m_->send_message (out, message); } } @@ -429,6 +457,7 @@ void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_tim NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_}; out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 () << low_confidence << off_air; + TRACE_UDP ("new" << is_new << "time:" << time << "snr:" << snr << "dt:" << delta_time << "df:" << delta_frequency << "mode:" << mode << "text:" << message_text << "low conf:" << low_confidence << "off air:" << off_air); m_->send_message (out, message); } } @@ -443,6 +472,7 @@ void MessageClient::WSPR_decode (bool is_new, QTime time, qint32 snr, float delt NetworkMessage::Builder out {&message, NetworkMessage::WSPRDecode, m_->id_, m_->schema_}; out << is_new << time << snr << delta_time << frequency << drift << callsign.toUtf8 () << grid.toUtf8 () << power << off_air; + TRACE_UDP ("new:" << is_new << "time:" << time << "snr:" << snr << "dt:" << delta_time << "frequency:" << frequency << "drift:" << drift << "call:" << callsign << "grid:" << grid << "pwr:" << power << "off air:" << off_air); m_->send_message (out, message); } } @@ -453,6 +483,7 @@ void MessageClient::clear_decodes () { QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::Clear, m_->id_, m_->schema_}; + TRACE_UDP (""); m_->send_message (out, message); } } @@ -473,6 +504,7 @@ void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QStr << report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 () << name.toUtf8 () << time_on << operator_call.toUtf8 () << my_call.toUtf8 () << my_grid.toUtf8 () << exchange_sent.toUtf8 () << exchange_rcvd.toUtf8 (); + TRACE_UDP ("time off:" << time_off << "DX:" << dx_call << "DX grid:" << dx_grid << "dial:" << dial_frequency << "mode:" << mode << "sent:" << report_sent << "rcvd:" << report_received << "pwr:" << tx_power << "comments:" << comments << "name:" << name << "time on:" << time_on << "op:" << operator_call << "DE:" << my_call << "DE grid:" << my_grid << "exch sent:" << exchange_sent << "exch rcvd:" << exchange_rcvd); m_->send_message (out, message); } } @@ -485,6 +517,7 @@ void MessageClient::logged_ADIF (QByteArray const& ADIF_record) NetworkMessage::Builder out {&message, NetworkMessage::LoggedADIF, m_->id_, m_->schema_}; QByteArray ADIF {"\n3.0.7\nWSJT-X\n\n" + ADIF_record + " "}; out << ADIF; + TRACE_UDP ("ADIF:" << ADIF); m_->send_message (out, message); } } diff --git a/wsjtx_config.h.in b/wsjtx_config.h.in index 39ea73329..22ff0f438 100644 --- a/wsjtx_config.h.in +++ b/wsjtx_config.h.in @@ -29,6 +29,7 @@ extern "C" { #cmakedefine01 WSJT_SOFT_KEYING #cmakedefine01 WSJT_ENABLE_EXPERIMENTAL_FEATURES #cmakedefine01 WSJT_RIG_NONE_CAN_SPLIT +#cmakedefine01 WSJT_TRACE_UDP #define WSJTX_STRINGIZE1(x) #x #define WSJTX_STRINGIZE(x) WSJTX_STRINGIZE1(x)