Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/Migration.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class DBSchemaMigration : public QObject
bool run(bool force = false);
static bool backupAllQSOsToADX(bool force = false);

static constexpr int latestVersion = 41;
static constexpr int latestVersion = 42;

private:
bool functionMigration(int version);
Expand Down
13 changes: 9 additions & 4 deletions data/RigProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ QDataStream& operator<<(QDataStream& out, const RigProfile& v)
<< v.getKeySpeed << v.assignedCWKey << v.keySpeedSync
<< v.driver << v.dxSpot2Rig << v.pttType << v.pttPortPath
<< v.rts << v.dtr << v.civAddr
<< v.shareRigctld << v.rigctldPort << v.rigctldPath << v.rigctldArgs << v.getSplitInfo;
<< v.shareRigctld << v.rigctldPort << v.rigctldPath << v.rigctldArgs << v.getSplitInfo << v.spotTuneCommand;

return out;
}
Expand Down Expand Up @@ -69,6 +69,7 @@ QDataStream& operator>>(QDataStream& in, RigProfile& v)
in >> v.rigctldPath;
in >> v.rigctldArgs;
in >> v.getSplitInfo;
in >> v.spotTuneCommand;

return in;
}
Expand All @@ -88,7 +89,8 @@ RigProfilesManager::RigProfilesManager() :
"key_speed_sync, driver, dxspot2rig, ptt_type, ptt_port_pathname, "
"IFNULL(rts, '%0'), IFNULL(dtr, '%0'), IFNULL(civaddr, -1), "
"IFNULL(share_rigctld, 0), IFNULL(rigctld_port, 4532), "
"IFNULL(rigctld_path, ''), IFNULL(rigctld_args, ''), get_split "
"IFNULL(rigctld_path, ''), IFNULL(rigctld_args, ''), get_split, "
"IFNULL(spot_tune_command, '') "
"FROM rig_profiles").arg(SerialPort::SERIAL_SIGNAL_NONE)))
{
qWarning()<< "Cannot prepare select";
Expand Down Expand Up @@ -138,6 +140,7 @@ RigProfilesManager::RigProfilesManager() :
profileDB.rigctldPath = profileQuery.value(36).toString();
profileDB.rigctldArgs = profileQuery.value(37).toString();
profileDB.getSplitInfo = profileQuery.value(38).toBool();
profileDB.spotTuneCommand = profileQuery.value(39).toString();

addProfile(profileDB.profileName, profileDB);
}
Expand Down Expand Up @@ -166,13 +169,13 @@ void RigProfilesManager::save()
"txfreq_end, get_freq, get_mode, get_vfo, get_pwr, rit_offset, xit_offset, get_rit, "
"get_xit, default_pwr, get_ptt, qsy_wiping, get_key_speed, assigned_cw_key, key_speed_sync, "
"driver, dxSpot2Rig, ptt_type, ptt_port_pathname, rts, dtr, civaddr, "
"share_rigctld, rigctld_port, rigctld_path, rigctld_args, get_split ) "
"share_rigctld, rigctld_port, rigctld_path, rigctld_args, get_split, spot_tune_command ) "
"VALUES (:profile_name, :model, :port_pathname, :hostname, :netport, "
":baudrate, :databits, :stopbits, :flowcontrol, :parity, :pollinterval, :txfreq_start, "
":txfreq_end, :get_freq, :get_mode, :get_vfo, :get_pwr, :rit_offset, :xit_offset, :get_rit, "
":get_xit, :default_pwr, :get_ptt, :qsy_wiping, :get_key_speed, :assigned_cw_key, :key_speed_sync, "
":driver, :dxSpot2Rig, :ptt_type, :ptt_port_pathname, :rts, :dtr, :civaddr, "
":share_rigctld, :rigctld_port, :rigctld_path, :rigctld_args, :get_split )") )
":share_rigctld, :rigctld_port, :rigctld_path, :rigctld_args, :get_split, :spot_tune_command )") )
{
qWarning() << "cannot prepare Insert statement";
return;
Expand Down Expand Up @@ -224,6 +227,7 @@ void RigProfilesManager::save()
insertQuery.bindValue(":rigctld_path", rigProfile.rigctldPath);
insertQuery.bindValue(":rigctld_args", rigProfile.rigctldArgs);
insertQuery.bindValue(":get_split", rigProfile.getSplitInfo);
insertQuery.bindValue(":spot_tune_command", rigProfile.spotTuneCommand);

if ( ! insertQuery.exec() )
{
Expand Down Expand Up @@ -280,6 +284,7 @@ bool RigProfile::operator==(const RigProfile &profile)
&& profile.rigctldPath == this->rigctldPath
&& profile.rigctldArgs == this->rigctldArgs
&& profile.getSplitInfo == this->getSplitInfo
&& profile.spotTuneCommand == this->spotTuneCommand
);
}

Expand Down
1 change: 1 addition & 0 deletions data/RigProfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class RigProfile
bool dxSpot2Rig;
bool shareRigctld;
bool getSplitInfo;
QString spotTuneCommand;

bool operator== (const RigProfile &profile);
bool operator!= (const RigProfile &profile);
Expand Down
1 change: 1 addition & 0 deletions res/res.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@
<file>sql/migration_039.sql</file>
<file>sql/migration_040.sql</file>
<file>sql/migration_041.sql</file>
<file>sql/migration_042.sql</file>
</qresource>
</RCC>
1 change: 1 addition & 0 deletions res/sql/migration_042.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE rig_profiles ADD COLUMN spot_tune_command TEXT;
24 changes: 24 additions & 0 deletions rig/Rig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,30 @@ void Rig::sendDXSpotImpl(const DxSpot &spot)
rigDriver->sendDXSpot(spot);
}

void Rig::sendRawCommand(const QString &command)
{
FCT_IDENTIFICATION;

qCDebug(function_parameters) << command;

QMetaObject::invokeMethod(this, "sendRawCommandImpl", Qt::QueuedConnection,
Q_ARG(QString, command));
}

void Rig::sendRawCommandImpl(const QString &command)
{
FCT_IDENTIFICATION;

qCDebug(function_parameters) << command;

MUTEXLOCKER;

if ( ! rigDriver )
return;

rigDriver->sendRawCommand(command);
}

GenericRigDrv *Rig::getDriver(const RigProfile &profile, qint32 controlledRigModel)
{
FCT_IDENTIFICATION;
Expand Down
2 changes: 2 additions & 0 deletions rig/Rig.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public slots:
void stopMorse();
void sendState();
void sendDXSpot(DxSpot spot);
void sendRawCommand(const QString &command);

signals:
void frequencyChanged(VFOID, double, double, double);
Expand Down Expand Up @@ -142,6 +143,7 @@ private slots:
void stopMorseImpl();
void sendStateImpl();
void sendDXSpotImpl(const DxSpot &spot);
void sendRawCommandImpl(const QString &command);
void sendHeartBeat();

private:
Expand Down
9 changes: 9 additions & 0 deletions rig/drivers/GenericRigDrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,12 @@ void GenericRigDrv::setSplit(bool)

// Default: do nothing — driver does not support split
}

void GenericRigDrv::sendRawCommand(const QString &command)
{
FCT_IDENTIFICATION;

qCDebug(function_parameters) << command;

// Default: do nothing - driver has no raw command channel
}
1 change: 1 addition & 0 deletions rig/drivers/GenericRigDrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class GenericRigDrv : public QObject
virtual void sendState() = 0;
virtual void stopTimers() = 0;
virtual void sendDXSpot(const DxSpot &spot) = 0;
virtual void sendRawCommand(const QString &command);

signals:
// STATE Signals
Expand Down
55 changes: 55 additions & 0 deletions rig/drivers/HamlibRigDrv.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <QtGlobal>
#include <QTcpSocket>

#include <QRegularExpression>
#include "HamlibRigDrv.h"
Expand Down Expand Up @@ -462,6 +463,60 @@ void HamlibRigDrv::setSplit(bool enabled)
commandSleep();
}

void HamlibRigDrv::sendRawCommand(const QString &command)
{
FCT_IDENTIFICATION;

qCDebug(function_parameters) << command;

MUTEXLOCKER;

if ( !rig )
{
qCWarning(runtime) << "Rig is not active";
return;
}

if ( rigProfile.model == RIG_MODEL_NETRIGCTL )
{
// The Hamlib link speaks the rigctld protocol, so raw bytes cannot go
// down that socket. rigctld takes further clients: a short second
// connection forwards the command with rigctld's "send_cmd_rx" and
// 0 reply bytes, so a set command returns at once and the protocol
// state of the Hamlib link is not touched.
QTcpSocket socket;

socket.connectToHost(rigProfile.hostname, rigProfile.netport);

if ( !socket.waitForConnected(1000) )
{
qCWarning(runtime) << "Raw command failed, rigctld not reachable" << command << socket.errorString();
return;
}

socket.write(QString("W %1 0\n").arg(command).toLatin1());
socket.waitForBytesWritten(1000);
socket.waitForReadyRead(1000); // rigctld's answer line, nothing to evaluate for a set command
socket.disconnectFromHost();
}
else
{
#if HAMLIB_VERSION >= HAMLIB_VERSION_CHECK(4,5,0)
const QByteArray bytes = command.toLatin1();
const int status = rig_send_raw(rig,
reinterpret_cast<const unsigned char *>(bytes.constData()), bytes.size(),
nullptr, 0, nullptr);

if ( status < 0 )
qCWarning(runtime) << "Raw command failed" << command << rigerror(status);
#else
qCWarning(runtime) << "Raw CAT commands need Hamlib 4.5 or newer" << command;
#endif
}

commandSleep();
}

void HamlibRigDrv::setRawMode(const QString &rawMode)
{
FCT_IDENTIFICATION;
Expand Down
1 change: 1 addition & 0 deletions rig/drivers/HamlibRigDrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class HamlibRigDrv : public GenericRigDrv
virtual void sendState() override;
virtual void stopTimers() override;
virtual void sendDXSpot(const DxSpot &spot) override;
virtual void sendRawCommand(const QString &command) override;

private slots:
void checkRigStateChange();
Expand Down
8 changes: 8 additions & 0 deletions ui/NewContactWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,14 @@ void NewContactWidget::tuneDx(const DxSpot &spot)
}
emit userModeChanged(VFO1, QString(), mode, subMode, bandwidthFilter);
}

// The rig profile may name a raw CAT command for the end of a spot
// tune, e.g. "SY2;" lets a Yaesu FTDX101 take its second receiver
// along to the same frequency and mode.
const QString &spotTuneCommand = RigProfilesManager::instance()->getCurProfile1().spotTuneCommand;

if ( !spotTuneCommand.isEmpty() )
rig->sendRawCommand(spotTuneCommand);
}

resetContact();
Expand Down
2 changes: 2 additions & 0 deletions ui/SettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ void SettingsDialog::addRigProfile()
profile.getKeySpeed = ui->rigGetKeySpeedCheckBox->isChecked();
profile.keySpeedSync = ui->rigKeySpeedSyncCheckBox->isChecked();
profile.dxSpot2Rig = ui->rigDXSpots2RigCheckBox->isChecked();
profile.spotTuneCommand = ui->rigSpotTuneCommandEdit->text().trimmed();
profile.getSplitInfo = ui->rigGetSplitCheckBox->isChecked();

// Rigctld sharing settings
Expand Down Expand Up @@ -1076,6 +1077,7 @@ void SettingsDialog::doubleClickRigProfile(QModelIndex i)
ui->rigGetKeySpeedCheckBox->setChecked(profile.getKeySpeed);
ui->rigKeySpeedSyncCheckBox->setChecked(profile.keySpeedSync);
ui->rigDXSpots2RigCheckBox->setChecked(profile.dxSpot2Rig);
ui->rigSpotTuneCommandEdit->setText(profile.spotTuneCommand);
ui->rigGetSplitCheckBox->setChecked(profile.getSplitInfo);

setComboByData(ui->rigFlowControlSelect, profile.flowcontrol.toLower());
Expand Down
17 changes: 17 additions & 0 deletions ui/SettingsDialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,23 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rigSpotTuneCommandLabel">
<property name="text">
<string>CAT after spot tuning:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="rigSpotTuneCommandEdit">
<property name="toolTip">
<string>Raw CAT command sent to the rig after QLog has tuned it to a spot. Example for the Yaesu FTDX101: SY2; synchronizes the second receiver (frequency and mode) with the main receiver. Leave empty if not needed.</string>
</property>
<property name="placeholderText">
<string>e.g. SY2;</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="11" column="1">
Expand Down