diff --git a/MessageClient.cpp b/MessageClient.cpp index 4c031a7d7..2a15fb19e 100644 --- a/MessageClient.cpp +++ b/MessageClient.cpp @@ -1,6 +1,8 @@ #include "MessageClient.hpp" #include +#include +#include #include #include @@ -76,6 +78,7 @@ public: QHostAddress server_; quint32 schema_; QTimer * heartbeat_timer_; + std::vector blocked_addresses_; // hold messages sent before host lookup completes asynchronously QQueue pending_messages_; @@ -93,15 +96,24 @@ void MessageClient::impl::host_info_results (QHostInfo host_info) } else if (host_info.addresses ().size ()) { - server_ = host_info.addresses ()[0]; - - // send initial heartbeat which allows schema negotiation - heartbeat (); - - // clear any backlog - while (pending_messages_.size ()) + auto server = host_info.addresses ()[0]; + if (blocked_addresses_.end () == std::find (blocked_addresses_.begin (), blocked_addresses_.end (), server)) { - send_message (pending_messages_.dequeue ()); + server_ = server; + + // send initial heartbeat which allows schema negotiation + heartbeat (); + + // clear any backlog + while (pending_messages_.size ()) + { + send_message (pending_messages_.dequeue ()); + } + } + else + { + Q_EMIT self_->error ("UDP server blocked, please try another"); + pending_messages_.clear (); // discard } } } @@ -349,6 +361,17 @@ void MessageClient::send_raw_datagram (QByteArray const& message, QHostAddress c } } +void MessageClient::add_blocked_destination (QHostAddress const& a) +{ + m_->blocked_addresses_.push_back (a); + if (a == m_->server_) + { + m_->server_.clear (); + Q_EMIT error ("UDP server blocked, please try another"); + m_->pending_messages_.clear (); // discard + } +} + void MessageClient::status_update (Frequency f, QString const& mode, QString const& dx_call , QString const& report, QString const& tx_mode , bool tx_enabled, bool transmitting, bool decoding diff --git a/MessageClient.hpp b/MessageClient.hpp index d641a66d7..957896f85 100644 --- a/MessageClient.hpp +++ b/MessageClient.hpp @@ -69,6 +69,10 @@ public: // UDP messaging if desired Q_SLOT void send_raw_datagram (QByteArray const&, QHostAddress const& dest_address, port_type dest_port); + // disallowed message destination (does not block datagrams sent + // with send_raw_datagram() above) + Q_SLOT void add_blocked_destination (QHostAddress const&); + // this signal is emitted if the server sends us a reply, the only // reply supported is reply to a prior CQ or QRZ message Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode diff --git a/psk_reporter.cpp b/psk_reporter.cpp index 38d10417a..b68a9c344 100644 --- a/psk_reporter.cpp +++ b/psk_reporter.cpp @@ -12,6 +12,11 @@ #include "moc_psk_reporter.cpp" +namespace +{ + int constexpr MAX_PAYLOAD_LENGTH {1400}; +} + PSK_Reporter::PSK_Reporter(MessageClient * message_client, QObject *parent) : QObject {parent}, m_messageClient {message_client}, @@ -68,10 +73,7 @@ void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QS void PSK_Reporter::sendReport() { - if (m_spotQueue.isEmpty()) { - return; - } - + while (!m_spotQueue.isEmpty()) { QString report_h; // Header @@ -91,15 +93,16 @@ void PSK_Reporter::sendReport() // Sender information QString txInfoData_h = "50E3llll"; - while (!m_spotQueue.isEmpty()) { - QHash spot = m_spotQueue.dequeue(); - txInfoData_h += QString("%1").arg(spot["call"].length(),2,16,QChar('0')) + spot["call"].toUtf8().toHex(); - txInfoData_h += QString("%1").arg(spot["freq"].toLongLong(),8,16,QChar('0')); - txInfoData_h += QString("%1").arg(spot["snr"].toInt(),8,16,QChar('0')).right(2); - txInfoData_h += QString("%1").arg(spot["mode"].length(),2,16,QChar('0')) + spot["mode"].toUtf8().toHex(); - txInfoData_h += QString("%1").arg(spot["grid"].length(),2,16,QChar('0')) + spot["grid"].toUtf8().toHex(); - txInfoData_h += QString("%1").arg(1,2,16,QChar('0')); // REPORTER_SOURCE_AUTOMATIC - txInfoData_h += QString("%1").arg(spot["time"].toInt(),8,16,QChar('0')); + while (!m_spotQueue.isEmpty() + && (header_h.size () + m_rxInfoDescriptor_h.size () + m_txInfoDescriptor_h.size () + rxInfoData_h.size () + txInfoData_h.size ()) / 2 < MAX_PAYLOAD_LENGTH) { + QHash spot = m_spotQueue.dequeue(); + txInfoData_h += QString("%1").arg(spot["call"].length(),2,16,QChar('0')) + spot["call"].toUtf8().toHex(); + txInfoData_h += QString("%1").arg(spot["freq"].toLongLong(),8,16,QChar('0')); + txInfoData_h += QString("%1").arg(spot["snr"].toInt(),8,16,QChar('0')).right(2); + txInfoData_h += QString("%1").arg(spot["mode"].length(),2,16,QChar('0')) + spot["mode"].toUtf8().toHex(); + txInfoData_h += QString("%1").arg(spot["grid"].length(),2,16,QChar('0')) + spot["grid"].toUtf8().toHex(); + txInfoData_h += QString("%1").arg(1,2,16,QChar('0')); // REPORTER_SOURCE_AUTOMATIC + txInfoData_h += QString("%1").arg(spot["time"].toInt(),8,16,QChar('0')); } txInfoData_h += "0000"; txInfoData_h.replace("50E3llll", "50E3" + QString("%1").arg(txInfoData_h.length()/2,4,16,QChar('0'))); @@ -113,14 +116,18 @@ void PSK_Reporter::sendReport() if (!m_pskReporterAddress.isNull()) { m_messageClient->send_raw_datagram (report, m_pskReporterAddress, 4739); } + } } void PSK_Reporter::dnsLookupResult(QHostInfo info) { if (!info.addresses().isEmpty()) { m_pskReporterAddress = info.addresses().at(0); -// qDebug() << "PSK Reporter IP: " << m_pskReporterAddress; + // qDebug() << "PSK Reporter IP: " << m_pskReporterAddress; + + // deal with miss-configured settings that attempt to set a + // Pskreporter Internet address for the WSJT-X UDP protocol + // server address + m_messageClient->add_blocked_destination (m_pskReporterAddress); } } - -