mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-03-22 12:08:43 -04:00
Add version and revision information to UDP heartbeat messages
Updated UDP examples to show the version and revision information received from clients. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7358 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
ac859c8f68
commit
2255b17e91
@ -21,9 +21,12 @@ class MessageClient::impl
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
impl (QString const& id, port_type server_port, MessageClient * self)
|
||||
impl (QString const& id, QString const& version, QString const& revision,
|
||||
port_type server_port, MessageClient * self)
|
||||
: self_ {self}
|
||||
, id_ {id}
|
||||
, version_ {version}
|
||||
, revision_ {revision}
|
||||
, server_port_ {server_port}
|
||||
, schema_ {2} // use 2 prior to negotiation not 1 which is broken
|
||||
, heartbeat_timer_ {new QTimer {this}}
|
||||
@ -66,6 +69,8 @@ public:
|
||||
|
||||
MessageClient * self_;
|
||||
QString id_;
|
||||
QString version_;
|
||||
QString revision_;
|
||||
QString server_string_;
|
||||
port_type server_port_;
|
||||
QHostAddress server_;
|
||||
@ -188,6 +193,11 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
|
||||
|
||||
default:
|
||||
// Ignore
|
||||
//
|
||||
// Note that although server heartbeat messages are not
|
||||
// parsed here they are still partially parsed in the
|
||||
// message reader class to negotiate the maximum schema
|
||||
// number being used on the network.
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -208,7 +218,8 @@ void MessageClient::impl::heartbeat ()
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder hb {&message, NetworkMessage::Heartbeat, id_, schema_};
|
||||
hb << NetworkMessage::Builder::schema_number; // maximum schema number accepted
|
||||
hb << NetworkMessage::Builder::schema_number // maximum schema number accepted
|
||||
<< version_.toUtf8 () << revision_.toUtf8 ();
|
||||
if (OK == check_status (hb))
|
||||
{
|
||||
writeDatagram (message, server_, server_port_);
|
||||
@ -273,9 +284,10 @@ auto MessageClient::impl::check_status (QDataStream const& stream) const -> Stre
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageClient::MessageClient (QString const& id, QString const& server, port_type server_port, QObject * self)
|
||||
MessageClient::MessageClient (QString const& id, QString const& version, QString const& revision,
|
||||
QString const& server, port_type server_port, QObject * self)
|
||||
: QObject {self}
|
||||
, m_ {id, server_port, this}
|
||||
, m_ {id, version, revision, server_port, this}
|
||||
{
|
||||
connect (&*m_, static_cast<void (impl::*) (impl::SocketError)> (&impl::error)
|
||||
, [this] (impl::SocketError e)
|
||||
|
@ -32,7 +32,8 @@ public:
|
||||
// instantiate and initiate a host lookup on the server
|
||||
//
|
||||
// messages will be silently dropped until a server host lookup is complete
|
||||
MessageClient (QString const& id, QString const& server, port_type server_port, QObject * parent = nullptr);
|
||||
MessageClient (QString const& id, QString const& version, QString const& revision,
|
||||
QString const& server, port_type server_port, QObject * parent = nullptr);
|
||||
|
||||
// query server details
|
||||
QHostAddress server_address () const;
|
||||
|
@ -21,8 +21,10 @@ class MessageServer::impl
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
impl (MessageServer * self)
|
||||
impl (MessageServer * self, QString const& version, QString const& revision)
|
||||
: self_ {self}
|
||||
, version_ {version}
|
||||
, revision_ {revision}
|
||||
, port_ {0u}
|
||||
, clock_ {new QTimer {this}}
|
||||
{
|
||||
@ -60,6 +62,8 @@ public:
|
||||
}
|
||||
|
||||
MessageServer * self_;
|
||||
QString version_;
|
||||
QString revision_;
|
||||
port_type port_;
|
||||
QHostAddress multicast_group_address_;
|
||||
static BindMode constexpr bind_mode_ = ShareAddress | ReuseAddressHint;
|
||||
@ -145,6 +149,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
||||
if (!clients_.contains (id))
|
||||
{
|
||||
auto& client = (clients_[id] = {sender, sender_port});
|
||||
QByteArray client_version;
|
||||
QByteArray client_revision;
|
||||
|
||||
if (NetworkMessage::Heartbeat == in.type ())
|
||||
{
|
||||
@ -159,7 +165,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
||||
// negotiated schema number
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder hb {&message, NetworkMessage::Heartbeat, id, client.negotiated_schema_number_};
|
||||
hb << NetworkMessage::Builder::schema_number; // maximum schema number accepted
|
||||
hb << NetworkMessage::Builder::schema_number // maximum schema number accepted
|
||||
<< version_.toUtf8 () << revision_.toUtf8 ();
|
||||
if (impl::OK == check_status (hb))
|
||||
{
|
||||
writeDatagram (message, client.sender_address_, client.sender_port_);
|
||||
@ -169,8 +176,11 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
||||
Q_EMIT self_->error ("Error creating UDP message");
|
||||
}
|
||||
}
|
||||
// we don't care if this fails to read
|
||||
in >> client_version >> client_revision;
|
||||
}
|
||||
Q_EMIT self_->client_opened (id);
|
||||
Q_EMIT self_->client_opened (id, QString::fromUtf8 (client_version),
|
||||
QString::fromUtf8 (client_revision));
|
||||
}
|
||||
clients_[id].last_activity_ = QDateTime::currentDateTime ();
|
||||
|
||||
@ -350,9 +360,9 @@ auto MessageServer::impl::check_status (QDataStream const& stream) const -> Stre
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageServer::MessageServer (QObject * parent)
|
||||
MessageServer::MessageServer (QObject * parent, QString const& version, QString const& revision)
|
||||
: QObject {parent}
|
||||
, m_ {this}
|
||||
, m_ {this, version, revision}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,14 @@ public:
|
||||
using port_type = quint16;
|
||||
using Frequency = Radio::Frequency;
|
||||
|
||||
MessageServer (QObject * parent = nullptr);
|
||||
MessageServer (QObject * parent = nullptr,
|
||||
QString const& version = QString {}, QString const& revision = QString {});
|
||||
|
||||
// start or restart the server, if the multicast_group_address
|
||||
// argument is given it is assumed to be a multicast group address
|
||||
// which the server will join
|
||||
Q_SLOT void start (port_type port, QHostAddress const& multicast_group_address = QHostAddress {});
|
||||
Q_SLOT void start (port_type port,
|
||||
QHostAddress const& multicast_group_address = QHostAddress {});
|
||||
|
||||
// ask the client with identification 'id' to make the same action
|
||||
// as a double click on the decode would
|
||||
@ -59,7 +61,7 @@ public:
|
||||
|
||||
// the following signals are emitted when a client broadcasts the
|
||||
// matching message
|
||||
Q_SIGNAL void client_opened (QString const& id);
|
||||
Q_SIGNAL void client_opened (QString const& id, QString const& version, QString const& revision);
|
||||
Q_SIGNAL void status_update (QString const& id, Frequency, QString const& mode, QString const& dx_call
|
||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
||||
|
@ -78,6 +78,8 @@
|
||||
* Heartbeat Out/In 0 quint32
|
||||
* Id (unique key) utf8
|
||||
* Maximum schema number quint32
|
||||
* version utf8
|
||||
* revision utf8
|
||||
*
|
||||
* The heartbeat message shall be sent on a periodic basis every
|
||||
* NetworkMessage::pulse seconds (see below), the WSJT-X
|
||||
|
@ -94,9 +94,27 @@ void ClientWidget::IdFilterModel::rx_df (int df)
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
QString make_title (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
QString title {id};
|
||||
if (version.size ())
|
||||
{
|
||||
title += QString {" v%1"}.arg (version);
|
||||
}
|
||||
if (revision.size ())
|
||||
{
|
||||
title += QString {" (%1)"}.arg (revision);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemModel * beacons_model
|
||||
, QString const& id, QWidget * parent)
|
||||
: QDockWidget {id, parent}
|
||||
, QString const& id, QString const& version, QString const& revision
|
||||
, QWidget * parent)
|
||||
: QDockWidget {make_title (id, version, revision), parent}
|
||||
, id_ {id}
|
||||
, decodes_proxy_model_ {id_}
|
||||
, decodes_table_view_ {new QTableView}
|
||||
|
@ -21,7 +21,8 @@ class ClientWidget
|
||||
|
||||
public:
|
||||
explicit ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemModel * beacons_model
|
||||
, QString const& id, QWidget * parent = nullptr);
|
||||
, QString const& id, QString const& version, QString const& revision
|
||||
, QWidget * parent = nullptr);
|
||||
|
||||
Q_SLOT void update_status (QString const& id, Frequency f, QString const& mode, QString const& dx_call
|
||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||
|
@ -126,9 +126,9 @@ void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time
|
||||
log_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::add_client (QString const& id)
|
||||
void MessageAggregatorMainWindow::add_client (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
auto dock = new ClientWidget {decodes_model_, beacons_model_, id, this};
|
||||
auto dock = new ClientWidget {decodes_model_, beacons_model_, id, version, revision, this};
|
||||
dock->setAttribute (Qt::WA_DeleteOnClose);
|
||||
auto view_action = dock->toggleViewAction ();
|
||||
view_action->setEnabled (true);
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
, QString const& name);
|
||||
|
||||
private:
|
||||
void add_client (QString const& id);
|
||||
void add_client (QString const& id, QString const& version, QString const& revision);
|
||||
void remove_client (QString const& id);
|
||||
|
||||
QStandardItemModel * log_;
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void add_client (QString const& id)
|
||||
void add_client (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
auto client = new Client {id};
|
||||
connect (server_, &MessageServer::status_update, client, &Client::update_status);
|
||||
@ -120,7 +120,16 @@ private:
|
||||
connect (server_, &MessageServer::WSPR_decode, client, &Client::beacon_spot_added);
|
||||
clients_[id] = client;
|
||||
server_->replay (id);
|
||||
std::cout << "Discovered WSJT-X instance: " << id.toStdString () << std::endl;
|
||||
std::cout << "Discovered WSJT-X instance: " << id.toStdString ();
|
||||
if (version.size ())
|
||||
{
|
||||
std::cout << " v" << version.toStdString ();
|
||||
}
|
||||
if (revision.size ())
|
||||
{
|
||||
std::cout << " (" << revision.toStdString () << ")";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void remove_client (QString const& id)
|
||||
|
@ -332,8 +332,9 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
"Please be patient,\n"
|
||||
"this may take a few minutes", QString {}, 0, 1, this},
|
||||
m_messageClient {new MessageClient {QApplication::applicationName (),
|
||||
m_config.udp_server_name (), m_config.udp_server_port (),
|
||||
this}},
|
||||
version (), revision (),
|
||||
m_config.udp_server_name (), m_config.udp_server_port (),
|
||||
this}},
|
||||
psk_Reporter {new PSK_Reporter {m_messageClient, this}},
|
||||
m_manual {network_manager}
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user