Skip to content

Commit

Permalink
WSJTX: Added support to received ADIF QSO Log record
Browse files Browse the repository at this point in the history
QLog can receive 2 QSO log messages. The first is a WSJTX binary log
message and the second is in ADIF format. QLog tries to get as much
information as possible from both and therefore merges them.
  • Loading branch information
foldynl committed May 28, 2024
1 parent ac7295d commit 12ef0b0
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 1 deletion.
2 changes: 2 additions & 0 deletions QLog.pro
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ SOURCES += \
core/QRZ.cpp \
core/QSLStorage.cpp \
core/SerialPort.cpp \
core/UpdatableSQLRecord.cpp \
core/Wsjtx.cpp \
core/debug.cpp \
core/main.cpp \
Expand Down Expand Up @@ -193,6 +194,7 @@ HEADERS += \
core/QRZ.h \
core/QSLStorage.h \
core/SerialPort.h \
core/UpdatableSQLRecord.h \
core/Wsjtx.h \
core/debug.h \
core/zonedetect.h \
Expand Down
95 changes: 95 additions & 0 deletions core/UpdatableSQLRecord.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <QSqlField>

#include "UpdatableSQLRecord.h"
#include "debug.h"

MODULE_IDENTIFICATION("qlog.core.updatableqslrecord");

UpdatableSQLRecord::UpdatableSQLRecord(int interval, QObject *parent)
: QObject{parent},
interval(interval)
{
FCT_IDENTIFICATION;

connect(&timer, &QTimer::timeout, this, &UpdatableSQLRecord::emitStoreRecord);
}

UpdatableSQLRecord::~UpdatableSQLRecord()
{
FCT_IDENTIFICATION;

timer.stop();
}

void UpdatableSQLRecord::updateRecord(const QSqlRecord &record)
{
FCT_IDENTIFICATION;

if ( internalRecord.isEmpty() )
{
internalRecord = record;
qCDebug(runtime) << "Record is empty, starting timer" << interval;
timer.start(interval);
return;
}
else if ( !matchQSO(QSOMatchingType, record) )
{
qCDebug(runtime) << "Records do not match";
timer.stop();
emitStoreRecord();
internalRecord = record;
}
else
{
qCDebug(runtime) << "Records match";

timer.stop();
for ( int i = 0; i < record.count(); ++i )
{
const QString &fieldName = record.fieldName(i);

if ( !internalRecord.contains(fieldName) )
internalRecord.append(record.field(i));
else if ( internalRecord.value(i).toString().isEmpty()
&& !record.value(i).toString().isEmpty() )
internalRecord.setValue(fieldName, record.value(i));
}
}

qCDebug(runtime) << "starting timer" << interval;
timer.start(interval);
}

void UpdatableSQLRecord::emitStoreRecord()
{
FCT_IDENTIFICATION;

timer.stop();

if ( internalRecord.isEmpty() )
return;

qCDebug(runtime) << "emitting record";
emit recordReady(internalRecord);
internalRecord.clear();
}

bool UpdatableSQLRecord::matchQSO(const MatchingType matchingType,
const QSqlRecord &record)
{
FCT_IDENTIFICATION;

const QStringList &fields = matchingFields.value(matchingType);

for ( const QString &fieldName : fields )
{
qCDebug(runtime) << "compare field name " << fieldName
<< "In value" << internalRecord.value(fieldName)
<< "New value" << record.value(fieldName);

if ( internalRecord.value(fieldName) != record.value(fieldName))
return false;
}

return true;
}
45 changes: 45 additions & 0 deletions core/UpdatableSQLRecord.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef UPDATABLESQLRECORD_H
#define UPDATABLESQLRECORD_H

#include <QObject>
#include <QSqlRecord>
#include <QTimer>
#include <QHash>

class UpdatableSQLRecord : public QObject
{
Q_OBJECT

public:
explicit UpdatableSQLRecord(int interval = 500,
QObject *parent = nullptr);

~UpdatableSQLRecord();
void updateRecord(const QSqlRecord &record);

signals:
void recordReady( QSqlRecord );

private slots:
void emitStoreRecord();

private:

enum MatchingType{
QSOMatchingType
};

QHash<MatchingType, QStringList> matchingFields
{
{QSOMatchingType, {"callsign", "mode", "submode"}}
};

bool matchQSO(const MatchingType,
const QSqlRecord &);

QSqlRecord internalRecord;
QTimer timer;
int interval;
};

#endif // UPDATABLESQLRECORD_H
42 changes: 41 additions & 1 deletion core/Wsjtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
#include <QDateTime>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QSqlField>

#include "Wsjtx.h"
#include "data/Data.h"
#include "debug.h"
#include "core/HostsPortString.h"
#include "rig/macros.h"
#include "data/BandPlan.h"
#include "logformat/AdiFormat.h"

MODULE_IDENTIFICATION("qlog.core.wsjtx");

Expand All @@ -25,6 +27,7 @@ Wsjtx::Wsjtx(QObject *parent) :
socket = new QUdpSocket(this);
openPort();
connect(socket, &QUdpSocket::readyRead, this, &Wsjtx::readPendingDatagrams);
connect(&wsjtSQLRecord, &UpdatableSQLRecord::recordReady, this, &Wsjtx::contactReady);
}

void Wsjtx::openPort()
Expand Down Expand Up @@ -384,7 +387,7 @@ void Wsjtx::readPendingDatagrams()
log.id = QString(id);
log.log_adif = QString(adif_text);

qCDebug(runtime) << log;
insertContact(log);
break;
}
}
Expand Down Expand Up @@ -504,9 +507,46 @@ void Wsjtx::insertContact(WsjtxLog log)
record.setValue("station_callsign", log.my_call);
}

// The QSO record can be received in two formats from WSJTX (raw and ADIF).
// Therefore, it is necessary to save the first record and possibly update it
// with the second record and then emit the result.
// For this we create an updatable SQLRecord
wsjtSQLRecord.updateRecord(record);
//emit addContact(record);
}

void Wsjtx::contactReady(QSqlRecord record)
{
FCT_IDENTIFICATION;

emit addContact(record);
}

void Wsjtx::insertContact(WsjtxLogADIF log)
{
FCT_IDENTIFICATION;

qCDebug(function_parameters) << log;

QSqlTableModel model;
model.setTable("contacts");
model.removeColumn(model.fieldIndex("id"));

QSqlRecord record = model.record(0);

QTextStream in(&log.log_adif);
AdiFormat adif(in);

adif.importNext(record);

// The QSO record can be received in two formats from WSJTX (raw and ADIF).
// Therefore, it is necessary to save the first record and possibly update it
// with the second record and then emit the result.
// For this we create an updatable SQLRecord
wsjtSQLRecord.updateRecord(record);
//emit addContact(record);
}

void Wsjtx::startReply(WsjtxDecode decode)
{
FCT_IDENTIFICATION;
Expand Down
6 changes: 6 additions & 0 deletions core/Wsjtx.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <QSqlRecord>
#include <QNetworkDatagram>

#include "core/UpdatableSQLRecord.h"

class Data;
class QUdpSocket;

Expand Down Expand Up @@ -149,12 +151,16 @@ public slots:
private slots:
void readPendingDatagrams();
void insertContact(WsjtxLog log);
void contactReady(QSqlRecord record);
void insertContact(WsjtxLogADIF log);

private:
QUdpSocket* socket;
QHostAddress wsjtxAddress;
quint16 wsjtxPort;

UpdatableSQLRecord wsjtSQLRecord;

static QString CONFIG_PORT;
static int DEFAULT_PORT;
static QString CONFIG_FORWARD_ADDRESSES;
Expand Down

0 comments on commit 12ef0b0

Please sign in to comment.