mirror of
https://github.com/JS8Call-improved/JS8Call-improved
synced 2026-08-13 17:47:36 -04:00
195 lines
5.7 KiB
C++
195 lines
5.7 KiB
C++
|
|
#include "TransceiverBase.h"
|
||
|
|
|
||
|
|
#include <exception>
|
||
|
|
|
||
|
|
#include <QDebug>
|
||
|
|
#include <QString>
|
||
|
|
#include <QThread>
|
||
|
|
#include <QTimer>
|
||
|
|
|
||
|
|
#include "moc_TransceiverBase.cpp"
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
auto const unexpected = TransceiverBase::tr("Unexpected rig error");
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::start(unsigned sequence_number) noexcept {
|
||
|
|
QString message;
|
||
|
|
try {
|
||
|
|
may_update u{this, true};
|
||
|
|
shutdown();
|
||
|
|
startup();
|
||
|
|
last_sequence_number_ = sequence_number;
|
||
|
|
} catch (std::exception const &e) {
|
||
|
|
message = e.what();
|
||
|
|
} catch (...) {
|
||
|
|
message = unexpected;
|
||
|
|
}
|
||
|
|
if (!message.isEmpty()) {
|
||
|
|
offline(message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::set(TransceiverState const &s,
|
||
|
|
unsigned sequence_number) noexcept {
|
||
|
|
TRACE_CAT("TransceiverBase", "#:" << sequence_number << s);
|
||
|
|
|
||
|
|
QString message;
|
||
|
|
try {
|
||
|
|
may_update u{this, true};
|
||
|
|
bool was_online{requested_.online()};
|
||
|
|
if (!s.online() && was_online) {
|
||
|
|
shutdown();
|
||
|
|
} else if (s.online() && !was_online) {
|
||
|
|
shutdown();
|
||
|
|
startup();
|
||
|
|
}
|
||
|
|
if (requested_.online()) {
|
||
|
|
bool ptt_on{false};
|
||
|
|
bool ptt_off{false};
|
||
|
|
if (s.ptt() != requested_.ptt()) {
|
||
|
|
ptt_on = s.ptt();
|
||
|
|
ptt_off = !s.ptt();
|
||
|
|
}
|
||
|
|
if (ptt_off) {
|
||
|
|
do_ptt(false);
|
||
|
|
do_post_ptt(false);
|
||
|
|
QThread::msleep(100); // some rigs cannot process CAT
|
||
|
|
// commands while switching from
|
||
|
|
// Tx to Rx
|
||
|
|
}
|
||
|
|
if (s.frequency() // ignore bogus zero frequencies
|
||
|
|
&& ((s.frequency() != requested_.frequency() // and QSY
|
||
|
|
|| (s.mode() != UNK &&
|
||
|
|
s.mode() != requested_.mode())) // or mode change
|
||
|
|
|| ptt_off)) // or just returned to rx
|
||
|
|
{
|
||
|
|
do_frequency(s.frequency(), s.mode(), ptt_off);
|
||
|
|
do_post_frequency(s.frequency(), s.mode());
|
||
|
|
|
||
|
|
// record what actually changed
|
||
|
|
requested_.frequency(actual_.frequency());
|
||
|
|
requested_.mode(actual_.mode());
|
||
|
|
}
|
||
|
|
if (!s.tx_frequency() ||
|
||
|
|
(s.tx_frequency() > 10000 // ignore bogus startup values
|
||
|
|
&& s.tx_frequency() <
|
||
|
|
std::numeric_limits<Frequency>::max() - 10000)) {
|
||
|
|
if ((s.tx_frequency() != requested_.tx_frequency() // and QSY
|
||
|
|
|| (s.mode() != UNK &&
|
||
|
|
s.mode() != requested_.mode())) // or mode change
|
||
|
|
// || s.split () != requested_.split ())) // or split change
|
||
|
|
|| (s.tx_frequency() && ptt_on)) // or about to tx split
|
||
|
|
{
|
||
|
|
hamlib_bug_bandaid(s);
|
||
|
|
do_tx_frequency(s.tx_frequency(), s.mode(), ptt_on);
|
||
|
|
do_post_tx_frequency(s.tx_frequency(), s.mode());
|
||
|
|
|
||
|
|
// record what actually changed
|
||
|
|
requested_.tx_frequency(actual_.tx_frequency());
|
||
|
|
requested_.split(actual_.split());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (ptt_on) {
|
||
|
|
do_ptt(true);
|
||
|
|
do_post_ptt(true);
|
||
|
|
QThread::msleep(100); // some rigs cannot process CAT
|
||
|
|
// commands while switching from
|
||
|
|
// Rx to Tx
|
||
|
|
}
|
||
|
|
|
||
|
|
// record what actually changed
|
||
|
|
requested_.ptt(actual_.ptt());
|
||
|
|
}
|
||
|
|
last_sequence_number_ = sequence_number;
|
||
|
|
} catch (std::exception const &e) {
|
||
|
|
message = e.what();
|
||
|
|
} catch (...) {
|
||
|
|
message = unexpected;
|
||
|
|
}
|
||
|
|
if (!message.isEmpty()) {
|
||
|
|
offline(message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::startup() {
|
||
|
|
Q_EMIT resolution(do_start());
|
||
|
|
do_post_start();
|
||
|
|
actual_.online(true);
|
||
|
|
requested_.online(true);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::shutdown() {
|
||
|
|
may_update u{this};
|
||
|
|
if (requested_.online()) {
|
||
|
|
try {
|
||
|
|
// try and ensure PTT isn't left set
|
||
|
|
do_ptt(false);
|
||
|
|
do_post_ptt(false);
|
||
|
|
if (requested_.split()) {
|
||
|
|
// try and reset split mode
|
||
|
|
do_tx_frequency(0, UNK, true);
|
||
|
|
do_post_tx_frequency(0, UNK);
|
||
|
|
}
|
||
|
|
} catch (...) {
|
||
|
|
// don't care about exceptions
|
||
|
|
}
|
||
|
|
}
|
||
|
|
do_stop();
|
||
|
|
do_post_stop();
|
||
|
|
actual_.online(false);
|
||
|
|
requested_.online(false);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::stop() noexcept {
|
||
|
|
QString message;
|
||
|
|
try {
|
||
|
|
shutdown();
|
||
|
|
} catch (std::exception const &e) {
|
||
|
|
message = e.what();
|
||
|
|
} catch (...) {
|
||
|
|
message = unexpected;
|
||
|
|
}
|
||
|
|
if (!message.isEmpty()) {
|
||
|
|
offline(message);
|
||
|
|
} else {
|
||
|
|
Q_EMIT finished();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::update_rx_frequency(Frequency rx) {
|
||
|
|
actual_.frequency(rx);
|
||
|
|
requested_.frequency(rx); // track rig changes
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::update_other_frequency(Frequency tx) {
|
||
|
|
actual_.tx_frequency(tx);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::update_split(bool state) { actual_.split(state); }
|
||
|
|
|
||
|
|
void TransceiverBase::update_mode(MODE m) {
|
||
|
|
actual_.mode(m);
|
||
|
|
requested_.mode(m); // track rig changes
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::update_PTT(bool state) { actual_.ptt(state); }
|
||
|
|
|
||
|
|
void TransceiverBase::update_complete(bool force_signal) {
|
||
|
|
if ((do_pre_update() && actual_ != last_) || force_signal) {
|
||
|
|
Q_EMIT update(actual_, last_sequence_number_);
|
||
|
|
last_ = actual_;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void TransceiverBase::offline(QString const &reason) {
|
||
|
|
Q_EMIT failure(reason);
|
||
|
|
try {
|
||
|
|
shutdown();
|
||
|
|
} catch (...) {
|
||
|
|
// don't care
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Q_LOGGING_CATEGORY(transceiverbase_js8, "transceiverbase.js8", QtWarningMsg)
|