Remove local event loops from Omni-Rig interface

Using a local event loop to wait for Omni-Rig to initialize has caused
issues elsewhere, reverted to simple waits in teh hope that Omni-Rig
initializes promptly.
This commit is contained in:
Bill Somerville 2021-07-30 20:21:57 +01:00
parent 25cb82b14d
commit aa1225ff96
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
10 changed files with 227 additions and 178 deletions

View File

@ -26,7 +26,7 @@ if (WIN32)
add_custom_command (
OUTPUT ${outfile}.h ${outfile}.cpp
COMMAND ${DUMPCPP_Executable}
ARGS ${AX_SERVER_options} -o "${outfile}" "${infile}"
ARGS ${ax_server_options} -o "${outfile}" "${infile}"
MAIN_DEPENDENCY ${infile} VERBATIM)
list (APPEND ${outfiles} ${outfile}.cpp)
endforeach()

View File

@ -2735,6 +2735,7 @@ bool Configuration::impl::open_rig (bool force)
ui_->test_CAT_push_button->setStyleSheet ({});
rig_active_ = true;
LOG_TRACE ("emitting startup_transceiver");
Q_EMIT start_transceiver (++transceiver_command_number_); // start rig on its thread
result = true;
}
@ -2782,6 +2783,7 @@ void Configuration::impl::transceiver_frequency (Frequency f)
cached_rig_state_.frequency (apply_calibration (f + current_offset_));
// qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
}
@ -2808,6 +2810,7 @@ void Configuration::impl::transceiver_tx_frequency (Frequency f)
}
// qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
}
}
@ -2817,6 +2820,7 @@ void Configuration::impl::transceiver_mode (MODE m)
cached_rig_state_.online (true); // we want the rig online
cached_rig_state_.mode (m);
// qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m;
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
}
@ -2826,6 +2830,7 @@ void Configuration::impl::transceiver_ptt (bool on)
set_cached_mode ();
cached_rig_state_.ptt (on);
// qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on;
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
}
@ -2909,6 +2914,7 @@ void Configuration::impl::close_rig ()
if (rig_active_)
{
ui_->test_CAT_push_button->setStyleSheet ("QPushButton {background-color: red;}");
LOG_TRACE ("emitting stop_transceiver");
Q_EMIT stop_transceiver ();
for (auto const& connection: rig_connections_)
{

View File

@ -42,6 +42,15 @@ namespace Radio
value = v.toDouble ();
if (ok) *ok = true;
}
if (ok && !*ok)
{
return value;
}
return frequency (value, scale, ok);
}
Frequency frequency (double value, int scale, bool * ok)
{
value *= std::pow (10., scale);
if (ok)
{
@ -50,6 +59,10 @@ namespace Radio
value = 0.;
*ok = false;
}
else
{
*ok = true;
}
}
return std::llround (value);
}
@ -66,6 +79,15 @@ namespace Radio
value = v.toDouble ();
if (ok) *ok = true;
}
if (ok && !*ok)
{
return value;
}
return frequency_delta (value, scale, ok);
}
FrequencyDelta frequency_delta (double value, int scale, bool * ok)
{
value *= std::pow (10., scale);
if (ok)
{
@ -75,6 +97,10 @@ namespace Radio
value = 0.;
*ok = false;
}
else
{
*ok = true;
}
}
return std::llround (value);
}

View File

@ -34,10 +34,12 @@ namespace Radio
// QVariant argument is convertible to double and is assumed to
// be scaled by (10 ** -scale).
//
Frequency UDP_EXPORT frequency (QVariant const&, int scale,
Frequency UDP_EXPORT frequency (QVariant const&, int scale = 0,
bool * ok = nullptr, QLocale const& = QLocale ());
FrequencyDelta UDP_EXPORT frequency_delta (QVariant const&, int scale,
FrequencyDelta UDP_EXPORT frequency_delta (QVariant const&, int scale = 0,
bool * ok = nullptr, QLocale const& = QLocale ());
Frequency UDP_EXPORT frequency (double, int scale = 0, bool * ok = nullptr);
FrequencyDelta UDP_EXPORT frequency_delta (double, int scale = 0, bool * ok = nullptr);
//
// Frequency type formatting

View File

@ -1128,7 +1128,7 @@ void HamlibTransceiver::do_poll ()
{
m_->error_check (rig_get_freq (m_->rig_.data (), RIG_VFO_CURR, &f), tr ("getting current VFO frequency"));
f = std::round (f);
CAT_TRACE ("rig_get_freq frequency=" << f);
CAT_TRACE ("rig_get_freq frequency=" << Radio::frequency (f));
update_rx_frequency (f);
}

View File

@ -96,11 +96,11 @@ void OmniRigTransceiver::register_transceivers (logger_type *,
};
}
OmniRigTransceiver::OmniRigTransceiver (logger_type * logger,
OmniRigTransceiver::OmniRigTransceiver (logger_type * the_logger,
std::unique_ptr<TransceiverBase> wrapped,
RigNumber n, TransceiverFactory::PTTMethod ptt_type,
QString const& ptt_port, QObject * parent)
: TransceiverBase {logger, parent}
: TransceiverBase {the_logger, parent}
, wrapped_ {std::move (wrapped)}
, use_for_ptt_ {TransceiverFactory::PTT_method_CAT == ptt_type || ("CAT" == ptt_port && (TransceiverFactory::PTT_method_RTS == ptt_type || TransceiverFactory::PTT_method_DTR == ptt_type))}
, ptt_type_ {ptt_type}
@ -111,26 +111,20 @@ OmniRigTransceiver::OmniRigTransceiver (logger_type * logger,
, reversed_ {false}
{
CoInitializeEx (nullptr, 0 /*COINIT_APARTMENTTHREADED*/); // required because Qt only does this for GUI thread
CAT_TRACE ("constructed");
}
OmniRigTransceiver::~OmniRigTransceiver ()
{
CAT_TRACE ("destroying");
CoUninitialize ();
}
// returns false on time out
bool OmniRigTransceiver::await_notification_with_timeout (int timeout)
{
QEventLoop el;
connect (this, &OmniRigTransceiver::notified, &el, [&el] () {el.exit (1);});
QTimer::singleShot (timeout, Qt::CoarseTimer, &el, [&el] () {el.exit (0);});
return 1 == el.exec (); // wait for notify or timer
}
int OmniRigTransceiver::do_start ()
{
CAT_TRACE ("starting");
try
{
if (wrapped_) wrapped_->start (0);
omni_rig_.reset (new OmniRig::OmniRigX {this});
@ -152,8 +146,10 @@ int OmniRigTransceiver::do_start ()
, SIGNAL (CustomReply (int, QVariant const&, QVariant const&))
, this, SLOT (handle_custom_reply (int, QVariant const&, QVariant const&)));
CAT_INFO ("OmniRig s/w version: " << omni_rig_->SoftwareVersion ()
<< "i/f version: " << omni_rig_->InterfaceVersion ());
CAT_INFO ("OmniRig s/w version: " << static_cast<quint16> (omni_rig_->SoftwareVersion () >> 16)
<< '.' << static_cast<quint16> (omni_rig_->SoftwareVersion () & 0xffff)
<< " i/f version: " << static_cast<int> (omni_rig_->InterfaceVersion () >> 8 & 0xff)
<< '.' << static_cast<int> (omni_rig_->InterfaceVersion () && 0xff));
// fetch the interface of the RigX CoClass and instantiate a proxy object
switch (rig_number_)
@ -168,12 +164,26 @@ int OmniRigTransceiver::do_start ()
// COM/OLE exceptions get signaled
connect (&*rig_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
offline_timer_.reset (new QTimer); // instantiate here as
// constructor runs in wrong
// thread
offline_timer_.reset (new QTimer); // instantiate here as constructor runs in wrong thread
offline_timer_->setSingleShot (true);
connect (offline_timer_.data (), &QTimer::timeout, [this] () {offline ("Rig went offline");});
for (int i = 0; i < 5; ++i)
{
// leave some time for Omni-Rig to do its first poll
QThread::msleep (250);
if (OmniRig::ST_ONLINE == rig_->Status ())
{
break;
}
}
if (OmniRig::ST_ONLINE != rig_->Status ())
{
CAT_ERROR ("rig not online");
throw_qstring ("OmniRig: " + rig_->StatusStr ());
}
if (use_for_ptt_ && (TransceiverFactory::PTT_method_DTR == ptt_type_ || TransceiverFactory::PTT_method_RTS == ptt_type_))
{
// fetch the interface for the serial port if we need it for PTT
@ -213,27 +223,7 @@ int OmniRigTransceiver::do_start ()
.arg (readable_params_, 8, 16, QChar ('0'))
.arg (writable_params_, 8, 16, QChar ('0'))
.arg (rig_number_));
for (int i = 0; i < 5; ++i)
{
if (OmniRig::ST_ONLINE == rig_->Status ())
{
break;
}
await_notification_with_timeout (1000);
}
if (OmniRig::ST_ONLINE != rig_->Status ())
{
throw_qstring ("OmniRig: " + rig_->StatusStr ());
}
QThread::msleep (500); // leave some time for Omni-Rig to get
// the rig status for the 1st. time
auto f = rig_->GetRxFrequency ();
for (int i = 0; (f == 0) && (i < 5); ++i)
{
await_notification_with_timeout (1000);
f = rig_->GetRxFrequency ();
}
update_rx_frequency (f);
update_rx_frequency (rig_->GetRxFrequency ());
int resolution {0};
if (OmniRig::PM_UNKNOWN == rig_->Vfo ()
&& (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
@ -243,7 +233,7 @@ int OmniRigTransceiver::do_start ()
// can't query VFO but can set explicitly
rig_->SetVfo (OmniRig::PM_VFOA);
}
f = state ().frequency ();
auto f = state ().frequency ();
if (f % 10) return resolution; // 1Hz resolution
auto test_frequency = f - f % 100 + 55;
if (OmniRig::PM_FREQ & writable_params_)
@ -262,11 +252,6 @@ int OmniRigTransceiver::do_start ()
{
throw_qstring (tr ("OmniRig: don't know how to set rig frequency"));
}
if (!await_notification_with_timeout (1000))
{
CAT_ERROR ("do_start 1: wait timed out");
throw_qstring (tr ("OmniRig: timeout waiting for update from rig"));
}
switch (rig_->GetRxFrequency () - test_frequency)
{
case -5: resolution = -1; break; // 10Hz truncated
@ -290,11 +275,6 @@ int OmniRigTransceiver::do_start ()
{
rig_->SetFreqA (test_frequency);
}
if (!await_notification_with_timeout (2000))
{
CAT_ERROR ("do_start 2: wait timed out");
throw_qstring (tr ("OmniRig: timeout waiting for update from rig"));
}
if (9 == rig_->GetRxFrequency () - test_frequency)
{
resolution = 2; // 20Hz rounded
@ -313,11 +293,20 @@ int OmniRigTransceiver::do_start ()
rig_->SetFreqA (f);
}
update_rx_frequency (f);
CAT_TRACE ("started");
return resolution;
}
catch (...)
{
CAT_TRACE ("start threw exception");
throw;
}
}
void OmniRigTransceiver::do_stop ()
{
CAT_TRACE ("stopping");
QThread::msleep (200); // leave some time for pending
// commands at the server end
@ -337,6 +326,7 @@ void OmniRigTransceiver::do_stop ()
{
rig_->clear ();
rig_.reset ();
CAT_TRACE ("rig_ reset");
}
omni_rig_->clear ();
omni_rig_.reset ();
@ -396,7 +386,6 @@ void OmniRigTransceiver::handle_status_change (int rig_number)
else
{
offline_timer_->stop (); // good to go again
Q_EMIT notified ();
}
// else
// {
@ -467,7 +456,6 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
if (params & OmniRig::PM_FREQ)
{
CAT_TRACE ("FREQ");
need_frequency = true;
}
if (params & OmniRig::PM_FREQA)
@ -653,7 +641,6 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
}
CAT_TRACE ("OmniRig params change: state after:" << state ());
}
Q_EMIT notified ();
}
void OmniRigTransceiver::handle_custom_reply (int rig_number, QVariant const& command, QVariant const& reply)
@ -710,7 +697,7 @@ void OmniRigTransceiver::do_ptt (bool on)
void OmniRigTransceiver::do_frequency (Frequency f, MODE m, bool /*no_ignore*/)
{
CAT_TRACE (f << state ());
CAT_TRACE (f << ' ' << state ());
if (!rig_ || rig_->isNull ()) return;
if (UNK != m)
{
@ -739,7 +726,7 @@ void OmniRigTransceiver::do_frequency (Frequency f, MODE m, bool /*no_ignore*/)
void OmniRigTransceiver::do_tx_frequency (Frequency tx, MODE m, bool /*no_ignore*/)
{
CAT_TRACE (tx << state ());
CAT_TRACE (tx << ' ' << state ());
if (!rig_ || rig_->isNull ()) return;
bool split {tx != 0};
if (split)
@ -804,7 +791,7 @@ void OmniRigTransceiver::do_tx_frequency (Frequency tx, MODE m, bool /*no_ignore
void OmniRigTransceiver::do_mode (MODE mode)
{
CAT_TRACE (mode << state ());
CAT_TRACE (mode << ' ' << state ());
if (!rig_ || rig_->isNull ()) return;
// TODO: G4WJS OmniRig doesn't seem to have any capability of tracking/setting VFO B mode
auto mapped = map_mode (mode);

View File

@ -44,9 +44,6 @@ public:
void do_ptt (bool on) override;
private:
bool await_notification_with_timeout (int timeout);
Q_SIGNAL void notified () const;
// Q_SLOT void timeout_check ();
Q_SLOT void handle_COM_exception (int, QString, QString, QString);
Q_SLOT void handle_visible_change ();
Q_SLOT void handle_rig_type_change (int rig_number);

View File

@ -23,6 +23,12 @@ QDebug operator << (QDebug d, Transceiver::TransceiverState const& s)
}
#endif
std::ostream& operator << (std::ostream& os, Transceiver::MODE m)
{
auto const& mo = Transceiver::staticMetaObject; \
return os << mo.enumerator (mo.indexOfEnumerator ("MODE")).valueToKey (static_cast<int> (m)); \
}
std::ostream& operator << (std::ostream& os, Transceiver::TransceiverState const& s)
{
return os

View File

@ -169,6 +169,7 @@ Q_DECLARE_METATYPE (Transceiver::TransceiverState);
QDebug operator << (QDebug, Transceiver::TransceiverState const&);
#endif
std::ostream& operator << (std::ostream&, Transceiver::MODE);
std::ostream& operator << (std::ostream&, Transceiver::TransceiverState const&);
ENUM_QDATASTREAM_OPS_DECL (Transceiver, MODE);

View File

@ -16,6 +16,8 @@ namespace
void TransceiverBase::start (unsigned sequence_number) noexcept
{
CAT_TRACE ("#: " << sequence_number);
QString message;
try
{
@ -26,10 +28,12 @@ void TransceiverBase::start (unsigned sequence_number) noexcept
}
catch (std::exception const& e)
{
CAT_TRACE ("#: " << sequence_number << " what: " << e.what ());
message = e.what ();
}
catch (...)
{
CAT_TRACE ("#: " << sequence_number);
message = unexpected;
}
if (!message.isEmpty ())
@ -41,7 +45,7 @@ void TransceiverBase::start (unsigned sequence_number) noexcept
void TransceiverBase::set (TransceiverState const& s,
unsigned sequence_number) noexcept
{
CAT_TRACE ("#: " << sequence_number << " " << s);
CAT_TRACE ("#: " << s);
QString message;
try
@ -119,10 +123,12 @@ void TransceiverBase::set (TransceiverState const& s,
}
catch (std::exception const& e)
{
CAT_TRACE ("#: " << sequence_number << " what: " << e.what ());
message = e.what ();
}
catch (...)
{
CAT_TRACE ("#: " << sequence_number << " " << sequence_number);
message = unexpected;
}
if (!message.isEmpty ())
@ -133,6 +139,7 @@ void TransceiverBase::set (TransceiverState const& s,
void TransceiverBase::startup ()
{
CAT_TRACE ("startup");
QString message;
try
{
@ -144,10 +151,12 @@ void TransceiverBase::startup ()
}
catch (std::exception const& e)
{
CAT_TRACE ("startup" << " what: " << e.what ());
message = e.what ();
}
catch (...)
{
CAT_TRACE ("startup");
message = unexpected;
}
if (!message.isEmpty ())
@ -158,6 +167,7 @@ void TransceiverBase::startup ()
void TransceiverBase::shutdown ()
{
CAT_TRACE ("shutdown");
may_update u {this};
if (requested_.online ())
{
@ -177,6 +187,7 @@ void TransceiverBase::shutdown ()
}
catch (...)
{
CAT_TRACE ("shutdown");
// don't care about exceptions
}
}
@ -186,6 +197,7 @@ void TransceiverBase::shutdown ()
void TransceiverBase::stop () noexcept
{
CAT_TRACE ("stop");
QString message;
try
{
@ -193,10 +205,12 @@ void TransceiverBase::stop () noexcept
}
catch (std::exception const& e)
{
CAT_TRACE ("stop" << " what: " << e.what ());
message = e.what ();
}
catch (...)
{
CAT_TRACE ("stop");
message = unexpected;
}
if (!message.isEmpty ())
@ -211,6 +225,7 @@ void TransceiverBase::stop () noexcept
void TransceiverBase::update_rx_frequency (Frequency rx)
{
CAT_TRACE ("frequency: " << rx);
if (rx)
{
actual_.frequency (rx);
@ -220,28 +235,35 @@ void TransceiverBase::update_rx_frequency (Frequency rx)
void TransceiverBase::update_other_frequency (Frequency tx)
{
CAT_TRACE ("frequency: " << tx);
actual_.tx_frequency (tx);
}
void TransceiverBase::update_split (bool state)
{
CAT_TRACE ("state: " << state);
actual_.split (state);
}
void TransceiverBase::update_mode (MODE m)
{
CAT_TRACE ("mode: " << m);
actual_.mode (m);
requested_.mode (m); // track rig changes
}
void TransceiverBase::update_PTT (bool state)
{
CAT_TRACE ("state: " << state);
actual_.ptt (state);
}
void TransceiverBase::update_complete (bool force_signal)
{
if ((do_pre_update () && actual_ != last_) || force_signal)
CAT_TRACE ("force signal: " << force_signal);
if ((do_pre_update ()
&& actual_ != last_)
|| force_signal)
{
Q_EMIT update (actual_, last_sequence_number_);
last_ = actual_;
@ -250,6 +272,7 @@ void TransceiverBase::update_complete (bool force_signal)
void TransceiverBase::offline (QString const& reason)
{
CAT_TRACE ("reason: " << reason);
Q_EMIT failure (reason);
try
{
@ -257,6 +280,7 @@ void TransceiverBase::offline (QString const& reason)
}
catch (...)
{
CAT_TRACE ("reason: " << reason);
// don't care
}
}