mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-03-24 13:08:34 -04:00
Broadcast logged QSOs to N1MM Logger+. Mostly thanks to Brian, N9ADG. Needs testing!
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8269 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
f62cadfa2d
commit
bc31f581bd
@ -567,6 +567,13 @@ private:
|
||||
QString opCall_;
|
||||
QString udp_server_name_;
|
||||
port_type udp_server_port_;
|
||||
// QString n1mm_server_name () const;
|
||||
QString n1mm_server_name_;
|
||||
port_type n1mm_server_port_;
|
||||
bool broadcast_to_n1mm_;
|
||||
// port_type n1mm_server_port () const;
|
||||
// bool valid_n1mm_info () const;
|
||||
// bool broadcast_to_n1mm() const;
|
||||
bool accept_udp_requests_;
|
||||
bool udpWindowToFront_;
|
||||
bool udpWindowRestore_;
|
||||
@ -662,6 +669,9 @@ QString Configuration::opCall() const {return m_->opCall_;}
|
||||
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
|
||||
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
|
||||
bool Configuration::accept_udp_requests () const {return m_->accept_udp_requests_;}
|
||||
QString Configuration::n1mm_server_name () const {return m_->n1mm_server_name_;}
|
||||
auto Configuration::n1mm_server_port () const -> port_type {return m_->n1mm_server_port_;}
|
||||
bool Configuration::broadcast_to_n1mm () const {return m_->broadcast_to_n1mm_;}
|
||||
bool Configuration::udpWindowToFront () const {return m_->udpWindowToFront_;}
|
||||
bool Configuration::udpWindowRestore () const {return m_->udpWindowRestore_;}
|
||||
Bands * Configuration::bands () {return &m_->bands_;}
|
||||
@ -772,6 +782,15 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s
|
||||
}
|
||||
}
|
||||
|
||||
bool Configuration::valid_n1mm_info () const
|
||||
{
|
||||
// do very rudimentary checking on the n1mm server name and port number.
|
||||
//
|
||||
auto server_name = m_->n1mm_server_name_;
|
||||
auto port_number = m_->n1mm_server_port_;
|
||||
return(!(server_name.trimmed().isEmpty() || port_number == 0));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined (Q_OS_MAC)
|
||||
@ -907,6 +926,9 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
ui_->udp_server_port_spin_box->setMinimum (1);
|
||||
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
|
||||
ui_->n1mm_server_port_spin_box->setMinimum (1);
|
||||
ui_->n1mm_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
|
||||
//
|
||||
// assign ids to radio buttons
|
||||
//
|
||||
@ -1145,6 +1167,9 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->udp_server_line_edit->setText (udp_server_name_);
|
||||
ui_->udp_server_port_spin_box->setValue (udp_server_port_);
|
||||
ui_->accept_udp_requests_check_box->setChecked (accept_udp_requests_);
|
||||
ui_->n1mm_server_name_line_edit->setText (n1mm_server_name_);
|
||||
ui_->n1mm_server_port_spin_box->setValue (n1mm_server_port_);
|
||||
ui_->enable_n1mm_broadcast_check_box->setChecked (broadcast_to_n1mm_);
|
||||
ui_->udpWindowToFront->setChecked(udpWindowToFront_);
|
||||
ui_->udpWindowRestore->setChecked(udpWindowRestore_);
|
||||
ui_->calibration_intercept_spin_box->setValue (calibration_.intercept);
|
||||
@ -1350,6 +1375,9 @@ void Configuration::impl::read_settings ()
|
||||
opCall_ = settings_->value ("OpCall", "").toString ();
|
||||
udp_server_name_ = settings_->value ("UDPServer", "127.0.0.1").toString ();
|
||||
udp_server_port_ = settings_->value ("UDPServerPort", 2237).toUInt ();
|
||||
n1mm_server_name_ = settings_->value ("N1MMServer", "127.0.0.1").toString ();
|
||||
n1mm_server_port_ = settings_->value ("N1MMServerPort", 2333).toUInt ();
|
||||
broadcast_to_n1mm_ = settings_->value ("BroadcastToN1MM", false).toBool ();
|
||||
accept_udp_requests_ = settings_->value ("AcceptUDPRequests", false).toBool ();
|
||||
udpWindowToFront_ = settings_->value ("udpWindowToFront",false).toBool ();
|
||||
udpWindowRestore_ = settings_->value ("udpWindowRestore",false).toBool ();
|
||||
@ -1449,6 +1477,9 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("OpCall", opCall_);
|
||||
settings_->setValue ("UDPServer", udp_server_name_);
|
||||
settings_->setValue ("UDPServerPort", udp_server_port_);
|
||||
settings_->setValue ("N1MMServer", n1mm_server_name_);
|
||||
settings_->setValue ("N1MMServerPort", n1mm_server_port_);
|
||||
settings_->setValue ("BroadcastToN1MM", broadcast_to_n1mm_);
|
||||
settings_->setValue ("AcceptUDPRequests", accept_udp_requests_);
|
||||
settings_->setValue ("udpWindowToFront", udpWindowToFront_);
|
||||
settings_->setValue ("udpWindowRestore", udpWindowRestore_);
|
||||
@ -1864,6 +1895,12 @@ void Configuration::impl::accept ()
|
||||
}
|
||||
|
||||
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
|
||||
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text ();
|
||||
n1mm_server_name_ = new_n1mm_server;
|
||||
auto new_n1mm_port = ui_->n1mm_server_port_spin_box->value ();
|
||||
n1mm_server_port_ = new_n1mm_port;
|
||||
broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked ();
|
||||
|
||||
udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
|
||||
udpWindowRestore_ = ui_->udpWindowRestore->isChecked ();
|
||||
|
||||
|
@ -139,6 +139,10 @@ public:
|
||||
QString opCall() const;
|
||||
QString udp_server_name () const;
|
||||
port_type udp_server_port () const;
|
||||
QString n1mm_server_name () const;
|
||||
port_type n1mm_server_port () const;
|
||||
bool valid_n1mm_info () const;
|
||||
bool broadcast_to_n1mm() const;
|
||||
bool accept_udp_requests () const;
|
||||
bool udpWindowToFront () const;
|
||||
bool udpWindowRestore () const;
|
||||
|
@ -1652,7 +1652,11 @@ QListView::item:hover {
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="opCallEntry"/>
|
||||
<widget class="QLineEdit" name="opCallEntry">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The callsign of the operator, if different from the station callsign.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="log_as_RTTY_check_box">
|
||||
@ -1821,6 +1825,60 @@ for assessing propagation and system performance.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="n1mm_group_box">
|
||||
<property name="title">
|
||||
<string>N1MM Logger+ Broadcasts</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_15">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="enable_n1mm_broadcast_check_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>When checked, WSJT-X will broadcast a logged contact in ADIF format to the configured hostname and port. </p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable logged contact ADIF broadcast</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QFormLayout" name="formLayout_20">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="n1mm_server_name_label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>N1MM Server name or IP address:</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="n1mm_server_name_line_edit">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Optional host name of N1MM Logger+ program to receive ADIF UDP broadcasts. This is usually 'localhost' or ip address 127.0.0.1</p><p>Formats:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hostname</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 multicast group address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 multicast group address</li></ul><p>Clearing this field will disable broadcasting of ADIF information via UDP.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="n1mm_server_port_label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>N1MM Server port number:</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="n1mm_server_port_spin_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enter the port number that WSJT-X should use for UDP broadcasts of ADIF log information. For N1MM Logger+, this value should be 2333. If this is zero, no updates will be broadcast.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
@ -2688,12 +2746,12 @@ soundcard changes</string>
|
||||
</connection>
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||
<buttongroup name="TX_audio_source_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="TX_mode_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
@ -14,7 +14,7 @@
|
||||
void ADIF::init(QString const& filename)
|
||||
{
|
||||
_filename = filename;
|
||||
_data.clear();
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -165,13 +165,47 @@ QList<QString> ADIF::getCallList() const
|
||||
++i;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ADIF::getCount() const
|
||||
{
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
QString ADIF::QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QString const& band,
|
||||
QString const& comments, QString const& name, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid, QString const& m_txPower)
|
||||
{
|
||||
QString t;
|
||||
t = "<call:" + QString::number(hisCall.length()) + ">" + hisCall;
|
||||
t += " <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid;
|
||||
t += " <mode:" + QString::number(mode.length()) + ">" + mode;
|
||||
t += " <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent;
|
||||
t += " <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd;
|
||||
t += " <qso_date:8>" + dateTimeOn.date().toString("yyyyMMdd");
|
||||
t += " <time_on:6>" + dateTimeOn.time().toString("hhmmss");
|
||||
t += " <qso_date_off:8>" + dateTimeOff.date().toString("yyyyMMdd");
|
||||
t += " <time_off:6>" + dateTimeOff.time().toString("hhmmss");
|
||||
t += " <band:" + QString::number(band.length()) + ">" + band;
|
||||
t += " <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq;
|
||||
t += " <station_callsign:" + QString::number(m_myCall.length()) + ">" +
|
||||
m_myCall;
|
||||
t += " <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" +
|
||||
m_myGrid;
|
||||
if (m_txPower != "")
|
||||
t += " <tx_pwr:" + QString::number(m_txPower.length()) +
|
||||
">" + m_txPower;
|
||||
if (comments != "")
|
||||
t += " <comment:" + QString::number(comments.length()) +
|
||||
">" + comments;
|
||||
if (name != "")
|
||||
t += " <name:" + QString::number(name.length()) +
|
||||
">" + name;
|
||||
t += " <eor>";
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
// open ADIF file and append the QSO details. Return true on success
|
||||
bool ADIF::addQSOToFile(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QString const& band,
|
||||
@ -187,30 +221,8 @@ bool ADIF::addQSOToFile(QString const& hisCall, QString const& hisGrid, QString
|
||||
out << "WSJT-X ADIF Export<eoh>" << endl; // new file
|
||||
|
||||
QString t;
|
||||
t="<call:" + QString::number(hisCall.length()) + ">" + hisCall;
|
||||
t+=" <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid;
|
||||
t+=" <mode:" + QString::number(mode.length()) + ">" + mode;
|
||||
t+=" <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent;
|
||||
t+=" <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd;
|
||||
t+=" <qso_date:8>" + dateTimeOn.date ().toString ("yyyyMMdd");
|
||||
t+=" <time_on:6>" + dateTimeOn.time ().toString ("hhmmss");
|
||||
t+=" <qso_date_off:8>" + dateTimeOff.date ().toString ("yyyyMMdd");
|
||||
t+=" <time_off:6>" + dateTimeOff.time ().toString ("hhmmss");
|
||||
t+=" <band:" + QString::number(band.length()) + ">" + band;
|
||||
t+=" <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq;
|
||||
t+=" <station_callsign:" + QString::number(m_myCall.length()) + ">" +
|
||||
m_myCall;
|
||||
t+=" <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" +
|
||||
m_myGrid;
|
||||
if(m_txPower!="") t+= " <tx_pwr:" + QString::number(m_txPower.length()) +
|
||||
">" + m_txPower;
|
||||
if(comments!="") t+=" <comment:" + QString::number(comments.length()) +
|
||||
">" + comments;
|
||||
if(name!="") t+=" <name:" + QString::number(name.length()) +
|
||||
">" + name;
|
||||
if(operator_call!="") t+=" <operator:" + QString::number(operator_call.length()) +
|
||||
">" + operator_call;
|
||||
t+=" <eor>";
|
||||
t = QSOToADIF(hisCall,hisGrid,mode,rptSent,rptRcvd,dateTimeOn,dateTimeOff,
|
||||
band,comments,name,strDialFreq,m_myCall,m_myGrid,m_txPower);
|
||||
out << t << endl;
|
||||
f2.close();
|
||||
}
|
||||
|
@ -32,7 +32,11 @@ class ADIF
|
||||
bool addQSOToFile(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QString const& band,
|
||||
QString const& comments, QString const& name, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid, QString const& m_txPower,QString const& operator_call);
|
||||
|
||||
private:
|
||||
QString QSOToADIF(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QString const& band,
|
||||
QString const& comments, QString const& name, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid, QString const& m_txPower);
|
||||
|
||||
|
||||
private:
|
||||
struct QSO
|
||||
{
|
||||
QString call,band,mode,date;
|
||||
|
16
logqso.cpp
16
logqso.cpp
@ -5,6 +5,7 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QUdpSocket>
|
||||
|
||||
#include "logbook/adif.h"
|
||||
#include "MessageBox.hpp"
|
||||
@ -85,6 +86,7 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
|
||||
ui->band->setText (m_config->bands ()->find (dialFreq));
|
||||
ui->loggedOperator->setText(opCall);
|
||||
show ();
|
||||
QTimer::singleShot(700, this, SLOT(accept()));
|
||||
}
|
||||
|
||||
void LogQSO::accept()
|
||||
@ -118,6 +120,20 @@ void LogQSO::accept()
|
||||
tr ("Cannot open \"%1\"").arg (adifilePath));
|
||||
}
|
||||
|
||||
// Log to N1MM Logger
|
||||
if (m_config->broadcast_to_n1mm() && m_config->valid_n1mm_info()) {
|
||||
QString adif = adifile.QSOToADIF(hisCall,hisGrid,mode,rptSent,rptRcvd,m_dateTimeOn,m_dateTimeOff,band,comments,name,strDialFreq,m_myCall,m_myGrid,m_txPower);
|
||||
const QHostAddress n1mmhost = QHostAddress(m_config->n1mm_server_name());
|
||||
QByteArray qba_adif = adif.toLatin1();
|
||||
QUdpSocket _sock;
|
||||
|
||||
auto rzult = _sock.writeDatagram ( qba_adif, n1mmhost, quint16(m_config->n1mm_server_port()));
|
||||
if (rzult == -1) {
|
||||
MessageBox::warning_message (this, tr ("Error sending log to N1MM"),
|
||||
tr ("Write returned \"%1\"").arg (errno));
|
||||
}
|
||||
}
|
||||
|
||||
//Log this QSO to file "wsjtx.log"
|
||||
static QFile f {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath ("wsjtx.log")};
|
||||
if(!f.open(QIODevice::Text | QIODevice::Append)) {
|
||||
|
Loading…
Reference in New Issue
Block a user