mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-03-29 23:52:24 -04:00
OTP for regular f/h mode
This commit is contained in:
parent
b0979968f3
commit
6997682425
@ -193,6 +193,7 @@
|
|||||||
#include "models/FrequencyList.hpp"
|
#include "models/FrequencyList.hpp"
|
||||||
#include "models/StationList.hpp"
|
#include "models/StationList.hpp"
|
||||||
#include "Network/NetworkServerLookup.hpp"
|
#include "Network/NetworkServerLookup.hpp"
|
||||||
|
#include "Network/FoxVerifier.hpp"
|
||||||
#include "widgets/MessageBox.hpp"
|
#include "widgets/MessageBox.hpp"
|
||||||
#include "validators/MaidenheadLocatorValidator.hpp"
|
#include "validators/MaidenheadLocatorValidator.hpp"
|
||||||
#include "validators/CallsignValidator.hpp"
|
#include "validators/CallsignValidator.hpp"
|
||||||
@ -596,6 +597,8 @@ private:
|
|||||||
Q_SLOT void on_rbARRL_Digi_clicked (bool);
|
Q_SLOT void on_rbARRL_Digi_clicked (bool);
|
||||||
Q_SLOT void on_cbSuperFox_clicked (bool);
|
Q_SLOT void on_cbSuperFox_clicked (bool);
|
||||||
Q_SLOT void on_cbContestName_clicked (bool);
|
Q_SLOT void on_cbContestName_clicked (bool);
|
||||||
|
Q_SLOT void on_cbOTP_clicked (bool);
|
||||||
|
|
||||||
void error_during_hamlib_download (QString const& reason);
|
void error_during_hamlib_download (QString const& reason);
|
||||||
void after_hamlib_downloaded();
|
void after_hamlib_downloaded();
|
||||||
void display_file_information();
|
void display_file_information();
|
||||||
@ -608,6 +611,8 @@ private:
|
|||||||
Q_SLOT void on_Field_Day_Exchange_textEdited (QString const&);
|
Q_SLOT void on_Field_Day_Exchange_textEdited (QString const&);
|
||||||
Q_SLOT void on_RTTY_Exchange_textEdited (QString const&);
|
Q_SLOT void on_RTTY_Exchange_textEdited (QString const&);
|
||||||
Q_SLOT void on_FoxKey_textEdited (QString const&);
|
Q_SLOT void on_FoxKey_textEdited (QString const&);
|
||||||
|
Q_SLOT void on_OTPUrl_textEdited (QString const&);
|
||||||
|
Q_SLOT void on_OTPSeed_textEdited (QString const&);
|
||||||
Q_SLOT void on_Contest_Name_textEdited (QString const&);
|
Q_SLOT void on_Contest_Name_textEdited (QString const&);
|
||||||
|
|
||||||
// typenames used as arguments must match registered type names :(
|
// typenames used as arguments must match registered type names :(
|
||||||
@ -708,6 +713,11 @@ private:
|
|||||||
QString hamlib_backed_up_;
|
QString hamlib_backed_up_;
|
||||||
QString FoxKey_;
|
QString FoxKey_;
|
||||||
|
|
||||||
|
QString OTPUrl_;
|
||||||
|
QString OTPSeed_;
|
||||||
|
bool OTPEnabled_;
|
||||||
|
qint32 OTPinterval_;
|
||||||
|
|
||||||
qint32 id_interval_;
|
qint32 id_interval_;
|
||||||
qint32 ntrials_;
|
qint32 ntrials_;
|
||||||
qint32 aggressive_;
|
qint32 aggressive_;
|
||||||
@ -978,6 +988,26 @@ void Configuration::invalidate_audio_output_device (QString /* error */)
|
|||||||
m_->audio_output_device_ = QAudioDeviceInfo {};
|
m_->audio_output_device_ = QAudioDeviceInfo {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OTP seed can be empty, in which case it is not used, or a valid 16 character base32 string.
|
||||||
|
bool Configuration::validate_otp_seed(QString seed)
|
||||||
|
{
|
||||||
|
if (seed.isEmpty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (seed.size() != 16)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (QChar c: seed)
|
||||||
|
{
|
||||||
|
if (!QString(BASE32_CHARSET).contains(c))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
bool Configuration::valid_n1mm_info () const
|
bool Configuration::valid_n1mm_info () const
|
||||||
{
|
{
|
||||||
// do very rudimentary checking on the n1mm server name and port number.
|
// do very rudimentary checking on the n1mm server name and port number.
|
||||||
@ -1084,6 +1114,26 @@ void Configuration::toggle_SF()
|
|||||||
m_->write_settings();
|
m_->write_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Configuration::OTPSeed() const
|
||||||
|
{
|
||||||
|
return m_->OTPSeed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Configuration::OTPUrl() const
|
||||||
|
{
|
||||||
|
return m_->OTPUrl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int Configuration::OTPinterval() const
|
||||||
|
{
|
||||||
|
return m_->OTPinterval_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Configuration::OTPEnabled() const
|
||||||
|
{
|
||||||
|
return m_->OTPSeed_.size() == 16 && m_->OTPEnabled_;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
#if defined (Q_OS_MAC)
|
#if defined (Q_OS_MAC)
|
||||||
@ -1254,6 +1304,8 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
ui_->add_macro_line_edit->setValidator (new QRegularExpressionValidator {message_alphabet, this});
|
ui_->add_macro_line_edit->setValidator (new QRegularExpressionValidator {message_alphabet, this});
|
||||||
ui_->Field_Day_Exchange->setValidator (new QRegularExpressionValidator {field_day_exchange_re, this});
|
ui_->Field_Day_Exchange->setValidator (new QRegularExpressionValidator {field_day_exchange_re, this});
|
||||||
ui_->RTTY_Exchange->setValidator (new QRegularExpressionValidator {RTTY_roundup_exchange_re, this});
|
ui_->RTTY_Exchange->setValidator (new QRegularExpressionValidator {RTTY_roundup_exchange_re, this});
|
||||||
|
QRegularExpression b32(QString("(^[") + QString(BASE32_CHARSET)+QString(BASE32_CHARSET).toLower() + QString("]{16}$)|(^$)"));
|
||||||
|
ui_->OTPSeed->setValidator(new QRegularExpressionValidator(b32, this));
|
||||||
|
|
||||||
//
|
//
|
||||||
// assign ids to radio buttons
|
// assign ids to radio buttons
|
||||||
@ -1619,6 +1671,16 @@ void Configuration::impl::read_settings ()
|
|||||||
ui_->Contest_Name->setText(Contest_Name_);
|
ui_->Contest_Name->setText(Contest_Name_);
|
||||||
hamlib_backed_up_ = settings_->value ("HamlibBackedUp",QString {}).toString ();
|
hamlib_backed_up_ = settings_->value ("HamlibBackedUp",QString {}).toString ();
|
||||||
|
|
||||||
|
OTPinterval_ = settings_->value ("OTPinterval", 3).toUInt ();
|
||||||
|
OTPUrl_ = settings_->value ("OTPUrl", FoxVerifier::default_url()).toString ();
|
||||||
|
OTPSeed_ = settings_->value ("OTPSeed", QString {}).toString ();
|
||||||
|
OTPEnabled_ = settings_->value ("OTPEnabled", false).toBool ();
|
||||||
|
|
||||||
|
ui_->sbOTPinterval->setValue(OTPinterval_);
|
||||||
|
ui_->OTPUrl->setText(OTPUrl_);
|
||||||
|
ui_->OTPSeed->setText(OTPSeed_);
|
||||||
|
ui_->cbOTP->setChecked(OTPEnabled_);
|
||||||
|
|
||||||
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
|
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
|
||||||
&& next_font_ != font_)
|
&& next_font_ != font_)
|
||||||
{
|
{
|
||||||
@ -1945,6 +2007,10 @@ void Configuration::impl::write_settings ()
|
|||||||
settings_->setValue ("AutoGrid", use_dynamic_grid_);
|
settings_->setValue ("AutoGrid", use_dynamic_grid_);
|
||||||
settings_->setValue ("highlight_DXcall", highlight_DXcall_);
|
settings_->setValue ("highlight_DXcall", highlight_DXcall_);
|
||||||
settings_->setValue ("highlight_DXgrid", highlight_DXgrid_);
|
settings_->setValue ("highlight_DXgrid", highlight_DXgrid_);
|
||||||
|
settings_->setValue ("OTPinterval", OTPinterval_);
|
||||||
|
settings_->setValue ("OTPUrl", OTPUrl_);
|
||||||
|
settings_->setValue ("OTPSeed", OTPSeed_);
|
||||||
|
settings_->setValue ("OTPEnabled", OTPEnabled_);
|
||||||
settings_->sync ();
|
settings_->sync ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2362,6 +2428,10 @@ void Configuration::impl::accept ()
|
|||||||
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
|
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
|
||||||
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
|
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
|
||||||
opCall_=ui_->opCallEntry->text();
|
opCall_=ui_->opCallEntry->text();
|
||||||
|
OTPinterval_=ui_->sbOTPinterval->value();
|
||||||
|
OTPSeed_=ui_->OTPSeed->text();
|
||||||
|
OTPUrl_=ui_->OTPUrl->text();
|
||||||
|
OTPEnabled_=ui_->cbOTP->isChecked();
|
||||||
|
|
||||||
auto new_server = ui_->udp_server_line_edit->text ().trimmed ();
|
auto new_server = ui_->udp_server_line_edit->text ().trimmed ();
|
||||||
auto new_interfaces = get_selected_network_interfaces (ui_->udp_interfaces_combo_box);
|
auto new_interfaces = get_selected_network_interfaces (ui_->udp_interfaces_combo_box);
|
||||||
@ -3211,6 +3281,11 @@ void Configuration::impl::on_cbContestName_clicked (bool)
|
|||||||
check_visibility ();
|
check_visibility ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::on_cbOTP_clicked(bool)
|
||||||
|
{
|
||||||
|
check_visibility();
|
||||||
|
}
|
||||||
|
|
||||||
void Configuration::impl::check_visibility ()
|
void Configuration::impl::check_visibility ()
|
||||||
{
|
{
|
||||||
if (ui_->rbFox->isChecked() and ui_->cbSuperFox->isChecked() and ui_->gbSpecialOpActivity->isChecked()) {
|
if (ui_->rbFox->isChecked() and ui_->cbSuperFox->isChecked() and ui_->gbSpecialOpActivity->isChecked()) {
|
||||||
@ -3253,6 +3328,53 @@ void Configuration::impl::check_visibility ()
|
|||||||
} else {
|
} else {
|
||||||
ui_->cbContestName->setEnabled (false);
|
ui_->cbContestName->setEnabled (false);
|
||||||
}
|
}
|
||||||
|
if (!ui_->cbOTP->isChecked() or !ui_->gbSpecialOpActivity->isChecked())
|
||||||
|
{
|
||||||
|
ui_->OTPSeed->setEnabled(false);
|
||||||
|
ui_->OTPUrl->setEnabled(false);
|
||||||
|
ui_->sbOTPinterval->setEnabled(false);
|
||||||
|
ui_->lblOTPSeed->setEnabled(false);
|
||||||
|
ui_->lblOTPUrl->setEnabled(false);
|
||||||
|
ui_->lblOTPEvery->setEnabled(false);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (ui_->rbHound->isChecked())
|
||||||
|
{
|
||||||
|
if (ui_->OTPUrl->text().isEmpty())
|
||||||
|
{
|
||||||
|
ui_->OTPUrl->setText(FoxVerifier::default_url());
|
||||||
|
}
|
||||||
|
ui_->OTPUrl->setEnabled(true);
|
||||||
|
ui_->lblOTPUrl->setEnabled(true);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ui_->OTPUrl->setEnabled(false);
|
||||||
|
ui_->lblOTPUrl->setEnabled(false);
|
||||||
|
}
|
||||||
|
if (ui_->rbFox->isChecked())
|
||||||
|
{
|
||||||
|
ui_->sbOTPinterval->setEnabled(true);
|
||||||
|
ui_->OTPSeed->setEnabled(true);
|
||||||
|
ui_->lblOTPSeed->setEnabled(true);
|
||||||
|
ui_->lblOTPEvery->setEnabled(true);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ui_->OTPSeed->setEnabled(false);
|
||||||
|
ui_->lblOTPSeed->setEnabled(false);
|
||||||
|
ui_->lblOTPEvery->setEnabled(false);
|
||||||
|
ui_->sbOTPinterval->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Configuration::impl::on_OTPUrl_textEdited (QString const& url){
|
||||||
|
auto text = url;
|
||||||
|
if (text.size() == 0)
|
||||||
|
{
|
||||||
|
ui_->OTPUrl->setText(FoxVerifier::default_url());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Configuration::impl::on_OTPSeed_textEdited (QString const& url){
|
||||||
|
ui_->OTPSeed->setText(url.toUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::impl::on_Field_Day_Exchange_textEdited (QString const& exchange)
|
void Configuration::impl::on_Field_Day_Exchange_textEdited (QString const& exchange)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "models/IARURegions.hpp"
|
#include "models/IARURegions.hpp"
|
||||||
#include "Audio/AudioDevice.hpp"
|
#include "Audio/AudioDevice.hpp"
|
||||||
#include "Transceiver/Transceiver.hpp"
|
#include "Transceiver/Transceiver.hpp"
|
||||||
|
#include "foxotpcode.h"
|
||||||
|
|
||||||
#include "pimpl_h.hpp"
|
#include "pimpl_h.hpp"
|
||||||
|
|
||||||
@ -193,7 +194,11 @@ public:
|
|||||||
bool highlight_DXcall () const;
|
bool highlight_DXcall () const;
|
||||||
bool highlight_DXgrid () const;
|
bool highlight_DXgrid () const;
|
||||||
bool Individual_Contest_Name() const;
|
bool Individual_Contest_Name() const;
|
||||||
|
bool validate_otp_seed(QString);
|
||||||
|
QString OTPSeed() const;
|
||||||
|
QString OTPUrl() const;
|
||||||
|
bool OTPEnabled() const;
|
||||||
|
u_int OTPinterval() const;
|
||||||
// 0 1 2 3 4 5 6 7 8 9
|
// 0 1 2 3 4 5 6 7 8 9
|
||||||
enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, WW_DIGI, FOX, HOUND, ARRL_DIGI, Q65_PILEUP};
|
enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, WW_DIGI, FOX, HOUND, ARRL_DIGI, Q65_PILEUP};
|
||||||
SpecialOperatingActivity special_op_id () const;
|
SpecialOperatingActivity special_op_id () const;
|
||||||
|
513
Configuration.ui
513
Configuration.ui
@ -2907,30 +2907,8 @@ Right click for insert and delete options.</string>
|
|||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,1,0,2">
|
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,0,0,0,0,0,0">
|
||||||
<item row="3" column="0">
|
<item row="2" column="6">
|
||||||
<widget class="QRadioButton" name="rbWW_DIGI">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>18</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>World-Wide Digi-mode contest</p><p><br/></p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleName">
|
|
||||||
<string>WW Digital Contest</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>WW Digi Contest</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_17" stretch="2,1,1">
|
<layout class="QHBoxLayout" name="horizontalLayout_17" stretch="2,1,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="rbField_Day">
|
<widget class="QRadioButton" name="rbField_Day">
|
||||||
@ -2999,7 +2977,293 @@ Right click for insert and delete options.</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="3">
|
<item row="1" column="2">
|
||||||
|
<widget class="QLineEdit" name="OTPUrl">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>URL used to verify OTP codes.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="cbOTP">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Click to enable OTP method of Fox verification. Requires internet.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>OTP</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbFox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string>Fox</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fox</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="5" colspan="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblOTPEvery">
|
||||||
|
<property name="text">
|
||||||
|
<string>OTP every</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="sbOTPinterval">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>How many cycles between sends of the OTP.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblOTPSeed">
|
||||||
|
<property name="text">
|
||||||
|
<string>OTP Key</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="OTPSeed">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Fox's key to generate OTP Codes.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbQ65pileup">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>18</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Exchange 4-character locator instead of signal report. Provides q3-level sensitivities for the DX operator. Especially useful for 6m EME DXpeditions.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Q65 Pileup</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4">
|
||||||
|
<spacer name="horizontalSpacer_11">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbWW_DIGI">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>18</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>World-Wide Digi-mode contest</p><p><br/></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string>WW Digital Contest</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>WW Digi Contest</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbNA_VHF_Contest">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string>NA VHF Contest</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>NA VHF</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="6">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cbContestName">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Call CQ with an individual contest name instead of TEST, RU, or WW. </p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>CQ with individual contest name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_12">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_25">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labCN">
|
||||||
|
<property name="text">
|
||||||
|
<string>Contest name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="Contest_Name">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="cursorPosition">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbEU_VHF_Contest">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string>EU VHF Contest</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>EU VHF Contest</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="lblOTPUrl">
|
||||||
|
<property name="text">
|
||||||
|
<string>OTP URL</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QRadioButton" name="rbHound">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string>Hound</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Hound</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="6">
|
||||||
|
<widget class="QRadioButton" name="rbARRL_Digi">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>ARRL International Digital Contest</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>ARRL Digi Contest</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="6">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_27" stretch="0,1,0,1">
|
<layout class="QHBoxLayout" name="horizontalLayout_27" stretch="0,1,0,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cbSuperFox">
|
<widget class="QCheckBox" name="cbSuperFox">
|
||||||
@ -3064,124 +3328,7 @@ Right click for insert and delete options.</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="3">
|
<item row="3" column="6">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cbContestName">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Call CQ with an individual contest name instead of TEST, RU, or WW. </p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>CQ with individual contest name</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_12">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_25">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labCN">
|
|
||||||
<property name="text">
|
|
||||||
<string>Contest name:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="Contest_Name">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>70</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="maxLength">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="cursorPosition">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbNA_VHF_Contest">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleName">
|
|
||||||
<string>NA VHF Contest</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>NA VHF</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbEU_VHF_Contest">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleName">
|
|
||||||
<string>EU VHF Contest</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>EU VHF Contest</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="3">
|
|
||||||
<widget class="QRadioButton" name="rbARRL_Digi">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>ARRL International Digital Contest</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>ARRL Digi Contest</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="3">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
|
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="rbRTTY_Roundup">
|
<widget class="QRadioButton" name="rbRTTY_Roundup">
|
||||||
@ -3250,76 +3397,6 @@ Right click for insert and delete options.</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbQ65pileup">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>18</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Exchange 4-character locator instead of signal report. Provides q3-level sensitivities for the DX operator. Especially useful for 6m EME DXpeditions.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Q65 Pileup</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QRadioButton" name="rbHound">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleName">
|
|
||||||
<string>Hound</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Hound</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbFox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="accessibleName">
|
|
||||||
<string>Fox</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Fox</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<spacer name="horizontalSpacer_11">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -3558,13 +3635,13 @@ Right click for insert and delete options.</string>
|
|||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="TX_mode_button_group"/>
|
|
||||||
<buttongroup name="PTT_method_button_group"/>
|
|
||||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
|
||||||
<buttongroup name="TX_audio_source_button_group"/>
|
|
||||||
<buttongroup name="special_op_activity_button_group"/>
|
|
||||||
<buttongroup name="CAT_data_bits_button_group"/>
|
<buttongroup name="CAT_data_bits_button_group"/>
|
||||||
<buttongroup name="CAT_handshake_button_group"/>
|
<buttongroup name="CAT_handshake_button_group"/>
|
||||||
<buttongroup name="split_mode_button_group"/>
|
<buttongroup name="split_mode_button_group"/>
|
||||||
|
<buttongroup name="TX_audio_source_button_group"/>
|
||||||
|
<buttongroup name="PTT_method_button_group"/>
|
||||||
|
<buttongroup name="TX_mode_button_group"/>
|
||||||
|
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||||
|
<buttongroup name="special_op_activity_button_group"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -51,6 +51,7 @@ bool FoxVerifier::finished() {
|
|||||||
return finished_;
|
return finished_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FoxVerifier::errorOccurred(QNetworkReply::NetworkError code)
|
void FoxVerifier::errorOccurred(QNetworkReply::NetworkError code)
|
||||||
{
|
{
|
||||||
int status = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int status = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
@ -109,3 +110,7 @@ QString FoxVerifier::formatDecodeMessage(QDateTime ts, QString callsign, QString
|
|||||||
else
|
else
|
||||||
return QString{};
|
return QString{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FoxVerifier::default_url() {
|
||||||
|
return QString(FOXVERIFIER_DEFAULT_BASE_URL);
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
|
||||||
#define FOXVERIFIER_DEFAULT_TIMEOUT_MSEC 5000
|
#define FOXVERIFIER_DEFAULT_TIMEOUT_MSEC 5000
|
||||||
#define FOXVERIFIER_DEFAULT_BASE_URL "https://www.9dx.ccm"
|
#define FOXVERIFIER_DEFAULT_BASE_URL "https://www.9dx.cc"
|
||||||
|
|
||||||
class FoxVerifier : public QObject {
|
class FoxVerifier : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -22,6 +22,7 @@ public:
|
|||||||
QString return_value;
|
QString return_value;
|
||||||
bool finished();
|
bool finished();
|
||||||
static QString formatDecodeMessage(QDateTime ts, QString callsign, QString const& verify_message);
|
static QString formatDecodeMessage(QDateTime ts, QString callsign, QString const& verify_message);
|
||||||
|
static QString default_url();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QNetworkAccessManager* manager_;
|
QNetworkAccessManager* manager_;
|
||||||
@ -57,4 +58,6 @@ signals:
|
|||||||
void verifyError(int status, QDateTime ts, QString callsign, QString code, QString const& response);
|
void verifyError(int status, QDateTime ts, QString callsign, QString code, QString const& response);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif //WSJTX2_FOXVERIFIER_HPP
|
#endif //WSJTX2_FOXVERIFIER_HPP
|
||||||
|
@ -4306,12 +4306,29 @@ void MainWindow::readFromStdout() //readFromStdout
|
|||||||
ARRL_Digi_Update(decodedtext1);
|
ARRL_Digi_Update(decodedtext1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui->labDXped->text() == "Super Hound" && (decodedtext0.mid(24, 8) == "$VERIFY$")) {
|
if ((SpecOp::HOUND == m_specOp) &&
|
||||||
|
((m_config.superFox() && (decodedtext0.mid(24, 8) == "$VERIFY$")) || // $VERIFY$ K8R 920749
|
||||||
|
(decodedtext0.mid(24, 8).contains(QRegularExpression{"^[A-Z0-9]{2,5}\\.V[0-9]{6}$"})))) // K8R.V920749
|
||||||
|
{
|
||||||
|
// two cases:
|
||||||
|
// QString test_return = QString{"203630 -12 0.1 775 ~ K8R.V920749"};
|
||||||
// $VERIFY$ foxcall otp
|
// $VERIFY$ foxcall otp
|
||||||
// QString test_return = QString{"203630 -12 0.1 775 ~ $VERIFY$ K8R 920749"};
|
// QString test_return = QString{"203630 -12 0.1 775 ~ $VERIFY$ K8R 920749"};
|
||||||
QStringList lineparts;
|
QStringList lineparts;
|
||||||
|
QStringList otp_parts;
|
||||||
|
QString callsign, otp;
|
||||||
lineparts = decodedtext0.string().split(' ', SkipEmptyParts);
|
lineparts = decodedtext0.string().split(' ', SkipEmptyParts);
|
||||||
|
if (lineparts.length() <= 6) {
|
||||||
|
// split K8R.V920749 into K8R and 920749
|
||||||
|
otp_parts = lineparts[5].split('.', SkipEmptyParts);
|
||||||
|
callsign = otp_parts[0];
|
||||||
|
otp = otp_parts[1].mid(1); // remove the V
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// split $VERIFY$ K8R 920749 into K8R and 920749
|
||||||
|
callsign = lineparts[6];
|
||||||
|
otp = lineparts[7];
|
||||||
|
}
|
||||||
QDateTime verifyDateTime;
|
QDateTime verifyDateTime;
|
||||||
if (m_diskData) {
|
if (m_diskData) {
|
||||||
verifyDateTime = m_UTCdiskDateTime; // get the date set from reading the wav file
|
verifyDateTime = m_UTCdiskDateTime; // get the date set from reading the wav file
|
||||||
@ -4322,9 +4339,9 @@ void MainWindow::readFromStdout() //readFromStdout
|
|||||||
FoxVerifier *fv = new FoxVerifier(MainWindow::userAgent(),
|
FoxVerifier *fv = new FoxVerifier(MainWindow::userAgent(),
|
||||||
&m_network_manager,
|
&m_network_manager,
|
||||||
FOXVERIFIER_DEFAULT_BASE_URL,
|
FOXVERIFIER_DEFAULT_BASE_URL,
|
||||||
lineparts[6], // foxcall
|
callsign, // foxcall
|
||||||
verifyDateTime,
|
verifyDateTime,
|
||||||
lineparts[7]); // otp
|
otp); // otp
|
||||||
connect(fv, &FoxVerifier::verifyComplete, this, &MainWindow::handleVerifyMsg);
|
connect(fv, &FoxVerifier::verifyComplete, this, &MainWindow::handleVerifyMsg);
|
||||||
m_verifications << fv;
|
m_verifications << fv;
|
||||||
} else {
|
} else {
|
||||||
@ -10185,6 +10202,33 @@ void MainWindow::on_comboBoxHoundSort_activated(int index)
|
|||||||
if(index!=-99) houndCallers(); //Silence compiler warning
|
if(index!=-99) houndCallers(); //Silence compiler warning
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString MainWindow::foxOTPcode()
|
||||||
|
{
|
||||||
|
QString code;
|
||||||
|
if (!m_config.OTPSeed().isEmpty())
|
||||||
|
{
|
||||||
|
char output[7];
|
||||||
|
QDateTime dateTime = dateTime.currentDateTime();
|
||||||
|
QByteArray ba = m_config.OTPSeed().toLocal8Bit();
|
||||||
|
char *c_str = ba.data();
|
||||||
|
int return_length;
|
||||||
|
if (6 == (return_length = create_totp(c_str, output, dateTime.toTime_t(), 30, 0)))
|
||||||
|
{
|
||||||
|
code = QString(output);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
code = "000000";
|
||||||
|
LOG_INFO(QString("foxOTPcode: Incorrect return length %1").arg(return_length));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
code = "000000";
|
||||||
|
showStatusMessage(tr("TOTP: No seed entered in fox configuration to generate verification code."));
|
||||||
|
LOG_INFO(QString("foxOTPcode: No seed entered in fox configuration to generate verification code."));
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
QString MainWindow::sortHoundCalls(QString t, int isort, int max_dB)
|
QString MainWindow::sortHoundCalls(QString t, int isort, int max_dB)
|
||||||
{
|
{
|
||||||
@ -10505,6 +10549,7 @@ void MainWindow::foxRxSequencer(QString msg, QString houndCall, QString rptRcvd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateFoxQSOsInProgressDisplay()
|
void MainWindow::updateFoxQSOsInProgressDisplay()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -10535,8 +10580,12 @@ void MainWindow::foxTxSequencer()
|
|||||||
QString hc,hc1,hc2; //Hound calls
|
QString hc,hc1,hc2; //Hound calls
|
||||||
QString t,rpt;
|
QString t,rpt;
|
||||||
qint32 islot=0;
|
qint32 islot=0;
|
||||||
|
qint32 ncalls_sent=0;
|
||||||
qint32 n1,n2,n3;
|
qint32 n1,n2,n3;
|
||||||
int nMaxRemainingSlots=0;
|
int nMaxRemainingSlots=0;
|
||||||
|
static u_int m_tFoxTxSinceOTP=99;
|
||||||
|
|
||||||
|
m_tFoxTxSinceOTP++;
|
||||||
m_tFoxTx++; //Increment Fox Tx cycle counter
|
m_tFoxTx++; //Increment Fox Tx cycle counter
|
||||||
|
|
||||||
//Is it time for a stand-alone CQ?
|
//Is it time for a stand-alone CQ?
|
||||||
@ -10552,15 +10601,27 @@ void MainWindow::foxTxSequencer()
|
|||||||
foxGenWaveform(islot-1,fm);
|
foxGenWaveform(islot-1,fm);
|
||||||
goto Transmit;
|
goto Transmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send OTP message maybe for regular fox mode
|
||||||
|
if (!m_config.superFox() && m_config.OTPEnabled() && (islot < m_Nslots) && (m_tFoxTxSinceOTP >= m_config.OTPinterval()))
|
||||||
|
{
|
||||||
|
// truncated callsign + OTP code (to be under 13 character limit of free text)
|
||||||
|
QString trunc_call=m_config.my_callsign().left(5).split("/").at(0);
|
||||||
|
fm = trunc_call + ".V" + foxOTPcode(); // N5J-> N5J.V123456, W1AW/7 -> W1AW.V123456, 4U1IARU -> 4U1IA.V123456
|
||||||
|
m_tFoxTxSinceOTP = 0; //Remember when we sent a Tx5
|
||||||
|
islot++;
|
||||||
|
foxGenWaveform(islot - 1, fm);
|
||||||
|
}
|
||||||
|
|
||||||
//Compile list1: up to NSLots Hound calls to be sent RR73
|
//Compile list1: up to NSLots Hound calls to be sent RR73
|
||||||
for(QString hc: m_foxQSO.keys()) { //Check all Hound calls: First priority
|
for(QString hc: m_foxQSO.keys()) { //Check all Hound calls: First priority
|
||||||
if(m_foxQSO[hc].tFoxRrpt<0) continue;
|
if(m_foxQSO[hc].tFoxRrpt<0) continue;
|
||||||
if(m_foxQSO[hc].tFoxRrpt - m_foxQSO[hc].tFoxTxRR73 > 3) {
|
if(m_foxQSO[hc].tFoxRrpt - m_foxQSO[hc].tFoxTxRR73 > 3) {
|
||||||
//Has been a long time since we sent RR73
|
//Has been a long time since we sent RR73
|
||||||
|
if(list1.size()>=(m_Nslots - islot)) goto list1Done;
|
||||||
list1 << hc; //Add to list1
|
list1 << hc; //Add to list1
|
||||||
m_foxQSO[hc].tFoxTxRR73 = m_tFoxTx; //Time RR73 is sent
|
m_foxQSO[hc].tFoxTxRR73 = m_tFoxTx; //Time RR73 is sent
|
||||||
m_foxQSO[hc].nRR73++; //Increment RR73 counter
|
m_foxQSO[hc].nRR73++; //Increment RR73 counter
|
||||||
if(list1.size()==m_Nslots) goto list1Done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10568,10 +10629,10 @@ void MainWindow::foxTxSequencer()
|
|||||||
if(m_foxQSO[hc].tFoxRrpt<0) continue;
|
if(m_foxQSO[hc].tFoxRrpt<0) continue;
|
||||||
if(m_foxQSO[hc].tFoxTxRR73 < 0) {
|
if(m_foxQSO[hc].tFoxTxRR73 < 0) {
|
||||||
//Have not yet sent RR73
|
//Have not yet sent RR73
|
||||||
|
if(list1.size()>=(m_Nslots - islot)) goto list1Done;
|
||||||
list1 << hc; //Add to list1
|
list1 << hc; //Add to list1
|
||||||
m_foxQSO[hc].tFoxTxRR73 = m_tFoxTx; //Time RR73 is sent
|
m_foxQSO[hc].tFoxTxRR73 = m_tFoxTx; //Time RR73 is sent
|
||||||
m_foxQSO[hc].nRR73++; //Increment RR73 counter
|
m_foxQSO[hc].nRR73++; //Increment RR73 counter
|
||||||
if(list1.size()==m_Nslots) goto list1Done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10579,10 +10640,10 @@ void MainWindow::foxTxSequencer()
|
|||||||
if(m_foxQSO[hc].tFoxRrpt<0) continue;
|
if(m_foxQSO[hc].tFoxRrpt<0) continue;
|
||||||
if(m_foxQSO[hc].tFoxTxRR73 <= m_foxQSO[hc].tFoxRrpt) {
|
if(m_foxQSO[hc].tFoxTxRR73 <= m_foxQSO[hc].tFoxRrpt) {
|
||||||
//We received R+rpt more recently than we sent RR73
|
//We received R+rpt more recently than we sent RR73
|
||||||
|
if(list1.size()>=(m_Nslots - islot)) goto list1Done;
|
||||||
list1 << hc; //Add to list1
|
list1 << hc; //Add to list1
|
||||||
m_foxQSO[hc].tFoxTxRR73 = m_tFoxTx; //Time RR73 is sent
|
m_foxQSO[hc].tFoxTxRR73 = m_tFoxTx; //Time RR73 is sent
|
||||||
m_foxQSO[hc].nRR73++; //Increment RR73 counter
|
m_foxQSO[hc].nRR73++; //Increment RR73 counter
|
||||||
if(list1.size()==m_Nslots) goto list1Done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10595,6 +10656,7 @@ list1Done:
|
|||||||
hc=m_foxQSOinProgress.at(i);
|
hc=m_foxQSOinProgress.at(i);
|
||||||
if((m_foxQSO[hc].tFoxRrpt < 0) and (m_foxQSO[hc].ncall < m_maxStrikes)) {
|
if((m_foxQSO[hc].tFoxRrpt < 0) and (m_foxQSO[hc].ncall < m_maxStrikes)) {
|
||||||
//Sent him a report and have not received R+rpt: call him again
|
//Sent him a report and have not received R+rpt: call him again
|
||||||
|
if(list2.size()>=(nMaxRemainingSlots - islot)) goto list2Done;
|
||||||
list2 << hc; //Add to list2
|
list2 << hc; //Add to list2
|
||||||
if(list2.size() == nMaxRemainingSlots) goto list2Done;
|
if(list2.size() == nMaxRemainingSlots) goto list2Done;
|
||||||
}
|
}
|
||||||
@ -10602,6 +10664,10 @@ list1Done:
|
|||||||
|
|
||||||
while(!m_houndQueue.isEmpty()) {
|
while(!m_houndQueue.isEmpty()) {
|
||||||
//Start QSO with a new Hound
|
//Start QSO with a new Hound
|
||||||
|
if (list2.size() == (nMaxRemainingSlots - islot))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
t=m_houndQueue.dequeue(); //Fetch new hound from queue
|
t=m_houndQueue.dequeue(); //Fetch new hound from queue
|
||||||
int i0=t.indexOf(" ");
|
int i0=t.indexOf(" ");
|
||||||
hc=t.mid(0,i0); //hound call
|
hc=t.mid(0,i0); //hound call
|
||||||
@ -10616,11 +10682,6 @@ list1Done:
|
|||||||
m_foxQSO[hc].tFoxRrpt = -1; //Have not received R+rpt
|
m_foxQSO[hc].tFoxRrpt = -1; //Have not received R+rpt
|
||||||
m_foxQSO[hc].tFoxTxRR73 = -1; //Have not sent RR73
|
m_foxQSO[hc].tFoxTxRR73 = -1; //Have not sent RR73
|
||||||
refreshHoundQueueDisplay();
|
refreshHoundQueueDisplay();
|
||||||
|
|
||||||
if(list2.size()==nMaxRemainingSlots) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list2Done:
|
list2Done:
|
||||||
@ -10680,12 +10741,13 @@ list2Done:
|
|||||||
fm = Radio::base_callsign(hc2) + " " + m_baseCall + " " + m_foxQSO[hc2].sent; //Standard FT8 message
|
fm = Radio::base_callsign(hc2) + " " + m_baseCall + " " + m_foxQSO[hc2].sent; //Standard FT8 message
|
||||||
}
|
}
|
||||||
islot++;
|
islot++;
|
||||||
|
ncalls_sent++;
|
||||||
foxGenWaveform(islot-1,fm); //Generate tx waveform
|
foxGenWaveform(islot-1,fm); //Generate tx waveform
|
||||||
}
|
}
|
||||||
|
|
||||||
if(islot < m_Nslots) {
|
if(islot < m_Nslots) {
|
||||||
//At least one slot is still open
|
//At least one slot is still open
|
||||||
if(islot==0 or ((m_tFoxTx-m_tFoxTx0>=4) and ui->cbMoreCQs->isChecked())) {
|
if(ncalls_sent==0 or ((m_tFoxTx-m_tFoxTx0>=4) and ui->cbMoreCQs->isChecked())) {
|
||||||
//Roughly every 4th Tx sequence, put a CQ message in an otherwise empty slot
|
//Roughly every 4th Tx sequence, put a CQ message in an otherwise empty slot
|
||||||
fm=ui->comboBoxCQ->currentText() + " " + m_config.my_callsign();
|
fm=ui->comboBoxCQ->currentText() + " " + m_config.my_callsign();
|
||||||
if(!fm.contains("/")) {
|
if(!fm.contains("/")) {
|
||||||
@ -11321,28 +11383,24 @@ void MainWindow::sfox_tx() {
|
|||||||
qint32 otp_key = 0;
|
qint32 otp_key = 0;
|
||||||
args.append(m_config.my_callsign());
|
args.append(m_config.my_callsign());
|
||||||
#ifdef FOX_OTP
|
#ifdef FOX_OTP
|
||||||
if (m_config.FoxKey().startsWith("OTP:", Qt::CaseInsensitive))
|
if (m_config.OTPEnabled())
|
||||||
{
|
{
|
||||||
LOG_INFO("OTP: Generating OTP key");
|
LOG_INFO("TOTP: Generating OTP key");
|
||||||
if (m_config.FoxKey().length() > 19) {
|
if (m_config.OTPSeed().length() == 16) {
|
||||||
QString foxCodeSeed = m_config.FoxKey().mid(4);
|
QString output=foxOTPcode();
|
||||||
char output[7];
|
if (6 == output.length())
|
||||||
QDateTime dateTime = dateTime.currentDateTime();
|
|
||||||
QByteArray ba = foxCodeSeed.toLocal8Bit();
|
|
||||||
char *c_str = ba.data();
|
|
||||||
int return_length;
|
|
||||||
if (6 == (return_length = create_totp(c_str, output, dateTime.toTime_t(), 30, 0)))
|
|
||||||
{
|
{
|
||||||
otp_key = QString(output).toInt();
|
otp_key = QString(output).toInt();
|
||||||
LOG_INFO(QString("TOTP: %1 [%2]").arg(output).arg(otp_key).toStdString());
|
LOG_INFO(QString("TOTP SF: %1 [%2]").arg(output).arg(otp_key).toStdString());
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
LOG_INFO(QString("TOTP: Incorrect return length %1").arg(return_length));
|
otp_key = 0;
|
||||||
|
LOG_INFO(QString("TOTP SF: Incorrect length"));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
showStatusMessage (tr ("TOTP: seed not long enough."));
|
showStatusMessage (tr ("TOTP SF: seed not long enough."));
|
||||||
LOG_INFO(QString("TOTP: seed not long enough"));
|
LOG_INFO(QString("TOTP SF: seed not long enough"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args.append(QString("OTP:%1").arg(otp_key));
|
args.append(QString("OTP:%1").arg(otp_key));
|
||||||
|
@ -898,6 +898,7 @@ private:
|
|||||||
QString userAgent();
|
QString userAgent();
|
||||||
void handleVerifyMsg(int status, QDateTime ts, QString callsign, QString code, QString const &response);
|
void handleVerifyMsg(int status, QDateTime ts, QString callsign, QString code, QString const &response);
|
||||||
void writeFoxTxMsgs();
|
void writeFoxTxMsgs();
|
||||||
|
QString foxOTPcode();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int killbyname(const char* progName);
|
extern int killbyname(const char* progName);
|
||||||
|
Loading…
Reference in New Issue
Block a user