LibreVNA TCP driver

This commit is contained in:
Jan Käberich 2023-01-29 18:02:32 +01:00
parent 80c5fc0ff6
commit 2c86cf1d6c
16 changed files with 550 additions and 33 deletions

View File

@ -420,6 +420,12 @@ bool LibreVNADriver::setExtRef(QString option_in, QString option_out)
return SendPacket(p); return SendPacket(p);
} }
void LibreVNADriver::registerTypes()
{
qRegisterMetaType<Protocol::PacketInfo>();
qRegisterMetaType<TransmissionResult>();
}
void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet) void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
{ {
emit passOnReceivedPacket(packet); emit passOnReceivedPacket(packet);
@ -533,7 +539,7 @@ void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
} }
} }
int LibreVNADriver::getMaxAmplitudePoints() const unsigned int LibreVNADriver::getMaxAmplitudePoints() const
{ {
return limits_maxAmplitudePoints; return limits_maxAmplitudePoints;
} }

View File

@ -141,6 +141,14 @@ public:
*/ */
virtual bool setExtRef(QString option_in, QString option_out) override; virtual bool setExtRef(QString option_in, QString option_out) override;
/**
* @brief Registers metatypes within the Qt Framework.
*
* If the device driver uses a queued signal/slot connection with custom data types, these types must be registered before emitting the signal.
* Register them within this function with qRegisterMetaType<Type>("Name");
*/
virtual void registerTypes();
public: public:
signals: signals:
// Required for the compound device driver // Required for the compound device driver
@ -149,7 +157,7 @@ public:
virtual bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500) = 0; virtual bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500) = 0;
bool sendWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb = nullptr); bool sendWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb = nullptr);
int getMaxAmplitudePoints() const; unsigned int getMaxAmplitudePoints() const;
signals: signals:
void receivedAnswer(const LibreVNADriver::TransmissionResult &result); void receivedAnswer(const LibreVNADriver::TransmissionResult &result);
@ -162,7 +170,7 @@ protected:
bool connected; bool connected;
QString serial; QString serial;
Info info; Info info;
int limits_maxAmplitudePoints; unsigned int limits_maxAmplitudePoints;
Protocol::DeviceStatusV1 lastStatus; Protocol::DeviceStatusV1 lastStatus;
@ -182,4 +190,8 @@ protected:
bool VNAAdjustPowerLevel; bool VNAAdjustPowerLevel;
}; };
Q_DECLARE_METATYPE(Protocol::PacketInfo)
Q_DECLARE_METATYPE(LibreVNADriver::TransmissionResult)
#endif // LIBREVNADRIVER_H #endif // LIBREVNADRIVER_H

View File

@ -0,0 +1,357 @@
#include "librevnatcpdriver.h"
#include "CustomWidgets/informationbox.h"
#include "../deviceusblog.h"
#include "Util/util.h"
#include <QTimer>
#include <QNetworkInterface>
using namespace std;
static const QString service_name = "urn:schemas-upnp-org:device:LibreVNA:1";
static constexpr int DataPort = 19544;
static constexpr int LogPort = 19545;
static auto SSDPaddress = QHostAddress("239.255.255.250");
static constexpr int SSDPport = 1900;
LibreVNATCPDriver::LibreVNATCPDriver()
: LibreVNADriver()
{
// dataSocket = nullptr;
// logSocket = nullptr;
connected = false;
m_receiveThread = nullptr;
auto interfaces = QNetworkInterface::allInterfaces();
for(auto i : interfaces) {
qDebug() << "Creating socket for interface" << i.name();
auto socket = new QUdpSocket();
socket->bind(QHostAddress::AnyIPv4, 0, QUdpSocket::ShareAddress);
socket->setMulticastInterface(i);
qDebug() << socket->joinMulticastGroup(SSDPaddress, i);
connect(socket, &QUdpSocket::readyRead, this, [=](){
SSDPreceived(socket);
});
ssdpSockets.push_back(socket);
}
}
QString LibreVNATCPDriver::getDriverName()
{
return "LibreVNA/TCP";
}
std::set<QString> LibreVNATCPDriver::GetAvailableDevices()
{
QByteArray data;
data.append("M-SEARCH * HTTP/1.1\r\n"
"HOST: 239.255.255.250:1900\r\n"
"MAN: \"ssdp:discover\"\r\n"
"MX: 1\r\n"
"ST: ");
data.append(service_name);
data.append("\r\n"
"\r\n");
pruneDetectedDevices();
for(auto s : ssdpSockets) {
s->writeDatagram(data.data(), SSDPaddress, SSDPport);
}
// TODO need delay here while still processing events
SynSleep::sleep(100);
std::set<QString> serials;
for(auto d : detectedDevices) {
serials.insert(d.serial);
}
return serials;
}
bool LibreVNATCPDriver::connectTo(QString serial)
{
if(connected) {
disconnect();
}
// check if this device is actually available
DetectedDevice devInfo;
bool available = false;
for(auto d : detectedDevices) {
if(d.serial == serial) {
devInfo = d;
available = true;
break;
}
}
if(!available) {
// no location information about this device available
return false;
}
// attempt to connect to the device
// dataSocket = new QTcpSocket();
// logSocket = new QTcpSocket();
dataSocket.connectToHost(devInfo.address, DataPort);
logSocket.connectToHost(devInfo.address, LogPort);
// check if connection succeeds
if(!dataSocket.waitForConnected(1000) || !logSocket.waitForConnected(1000)) {
// at least one socket failed
dataSocket.close();
logSocket.close();
// delete dataSocket;
// delete logSocket;
// dataSocket = nullptr;
// logSocket = nullptr;
InformationBox::ShowError("Error", "TCP connection timed out");
return false;
}
// sockets are connected now
dataBuffer.clear();
logBuffer.clear();
connect(&dataSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &LibreVNATCPDriver::ConnectionLost, Qt::QueuedConnection);
connect(&logSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &LibreVNATCPDriver::ConnectionLost, Qt::QueuedConnection);
qInfo() << "TCP connection established" << flush;
this->serial = serial;
connected = true;
connect(&dataSocket, &QTcpSocket::readyRead, this, &LibreVNATCPDriver::ReceivedData, Qt::UniqueConnection);
connect(&logSocket, &QTcpSocket::readyRead, this, &LibreVNATCPDriver::ReceivedLog, Qt::UniqueConnection);
connect(&transmissionTimer, &QTimer::timeout, this, &LibreVNATCPDriver::transmissionTimeout, Qt::UniqueConnection);
connect(this, &LibreVNATCPDriver::receivedAnswer, this, &LibreVNATCPDriver::transmissionFinished, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
connect(this, &LibreVNATCPDriver::receivedPacket, this, &LibreVNATCPDriver::handleReceivedPacket, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
transmissionTimer.setSingleShot(true);
transmissionActive = false;
sendWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
sendWithoutPayload(Protocol::PacketType::RequestDeviceStatus);
return true;
}
void LibreVNATCPDriver::disconnect()
{
if(connected) {
setIdle();
transmissionTimer.stop();
transmissionQueue.clear();
transmissionActive = false;
dataSocket.close();
logSocket.close();
// delete dataSocket;
// delete logSocket;
// dataSocket = nullptr;
// logSocket = nullptr;
connected = false;
serial = "";
}
}
void LibreVNATCPDriver::registerTypes()
{
qDebug() << "Registering meta type: " << qRegisterMetaType<Protocol::PacketInfo>();
qDebug() << "Registering meta type: " << qRegisterMetaType<TransmissionResult>();
}
void LibreVNATCPDriver::SSDPreceived(QUdpSocket *sock)
{
while(sock->hasPendingDatagrams()) {
QHostAddress sender;
quint16 senderPort;
QByteArray buf(sock->pendingDatagramSize(), Qt::Uninitialized);
QDataStream str(&buf, QIODevice::ReadOnly);
sock->readDatagram(buf.data(), buf.size(), &sender, &senderPort);
QString ssdp_string = QString(buf);
auto lines = ssdp_string.split("\r\n");
QString location, st, serial, max_age;
if(lines[0] != "HTTP/1.1 200 OK") {
continue;
}
for(QString l : lines) {
if(l.startsWith("LOCATION:")) {
location = l.split(" ")[1];
} else if(l.startsWith("ST:")) {
st = l.split(" ")[1];
} else if(l.startsWith("LibreVNA-serial:")) {
serial = l.split(" ")[1];
} else if(l.startsWith("CACHE-CONTROL:")) {
max_age = l.split("=")[1];
}
}
if(location.isEmpty() || st.isEmpty() || serial.isEmpty() || max_age.isEmpty()) {
// some required field is missing
continue;
}
// new device
DetectedDevice d;
d.address = QHostAddress(location);
d.maxAgeSeconds = max_age.toUInt();
d.responseTime = QDateTime::currentDateTime();
d.serial = serial;
addDetectedDevice(d);
}
}
void LibreVNATCPDriver::ReceivedData()
{
dataBuffer.append(dataSocket.readAll());
Protocol::PacketInfo packet;
uint16_t handled_len;
// qDebug() << "Received data";
do {
// qDebug() << "Decoding" << dataBuffer->getReceived() << "Bytes";
handled_len = Protocol::DecodeBuffer((uint8_t*) dataBuffer.data(), dataBuffer.size(), &packet);
// qDebug() << "Handled" << handled_len << "Bytes, type:" << (int) packet.type;
if(handled_len > 0) {
auto &log = DeviceUSBLog::getInstance();
if(packet.type != Protocol::PacketType::None) {
log.addPacket(packet, serial);
} else {
log.addInvalidBytes((uint8_t*) dataBuffer.data(), handled_len, serial);
}
}
dataBuffer.remove(0, handled_len);
switch(packet.type) {
case Protocol::PacketType::Ack:
emit receivedAnswer(TransmissionResult::Ack);
break;
case Protocol::PacketType::Nack:
emit receivedAnswer(TransmissionResult::Nack);
break;
default:
// pass on to LibreVNADriver class
emit receivedPacket(packet);
break;
}
} while (handled_len > 0);
}
void LibreVNATCPDriver::ReceivedLog()
{
logBuffer.append(logSocket.readAll());
uint16_t handled_len;
do {
handled_len = 0;
auto firstLinebreak = (uint8_t*) memchr((uint8_t*) logBuffer.data(), '\n', logBuffer.size());
if(firstLinebreak) {
handled_len = firstLinebreak - (uint8_t*) logBuffer.data();
auto line = QString::fromLatin1(logBuffer.data(), handled_len - 1);
emit LogLineReceived(line);
logBuffer.remove(0, handled_len + 1);
}
} while(handled_len > 0);
}
void LibreVNATCPDriver::transmissionFinished(LibreVNADriver::TransmissionResult result)
{
lock_guard<mutex> lock(transmissionMutex);
// remove transmitted packet
// qDebug() << "Transmission finsished (" << result << "), queue at " << transmissionQueue.size() << " Outstanding ACKs:"<<outstandingAckCount;
if(transmissionQueue.empty()) {
qWarning() << "transmissionFinished with empty transmission queue, stray Ack? Result:" << result;
return;
}
auto t = transmissionQueue.dequeue();
if(result == TransmissionResult::Timeout) {
qWarning() << "transmissionFinished with timeout, packettype:" << (int) t.packet.type << "Device:" << serial;
}
if(result == TransmissionResult::Nack) {
qWarning() << "transmissionFinished with NACK";
}
if(t.callback) {
t.callback(result);
}
transmissionTimer.stop();
bool success = false;
while(!transmissionQueue.isEmpty() && !success) {
success = startNextTransmission();
if(!success) {
// failed to send this packet
auto t = transmissionQueue.dequeue();
if(t.callback) {
t.callback(TransmissionResult::InternalError);
}
}
}
if(transmissionQueue.isEmpty()) {
transmissionActive = false;
}
}
bool LibreVNATCPDriver::SendPacket(const Protocol::PacketInfo &packet, std::function<void (LibreVNADriver::TransmissionResult)> cb, unsigned int timeout)
{
Transmission t;
t.packet = packet;
t.timeout = timeout;
t.callback = cb;
lock_guard<mutex> lock(transmissionMutex);
transmissionQueue.enqueue(t);
// qDebug() << "Enqueued packet, queue at " << transmissionQueue.size();
if(!transmissionActive) {
startNextTransmission();
}
return true;
}
void LibreVNATCPDriver::addDetectedDevice(const LibreVNATCPDriver::DetectedDevice &d)
{
for(auto &e : detectedDevices) {
if(e.serial == d.serial) {
// replace entry
e = d;
return;
}
}
// serial not already present, add
detectedDevices.push_back(d);
}
void LibreVNATCPDriver::pruneDetectedDevices()
{
for(unsigned int i=0;i<detectedDevices.size();i++) {
auto d = detectedDevices[i];
if(d.responseTime.secsTo(QDateTime::currentDateTime()) > d.maxAgeSeconds) {
// too old, remove
detectedDevices.erase(detectedDevices.begin()+i);
i--;
}
}
}
bool LibreVNATCPDriver::startNextTransmission()
{
if(transmissionQueue.isEmpty() || !connected) {
// nothing more to transmit
transmissionActive = false;
return false;
}
transmissionActive = true;
auto t = transmissionQueue.head();
unsigned char buffer[1024];
unsigned int length = Protocol::EncodePacket(t.packet, buffer, sizeof(buffer));
if(!length) {
qCritical() << "Failed to encode packet";
return false;
}
auto &log = DeviceUSBLog::getInstance();
log.addPacket(t.packet);
auto ret = dataSocket.write((char*) buffer, length);
if(ret < 0) {
qCritical() << "Error sending TCP data";
return false;
}
transmissionTimer.start(t.timeout);
// qDebug() << "Transmission started, queue at " << transmissionQueue.size();
return true;
}

View File

@ -0,0 +1,107 @@
#ifndef LIBREVNATCPDRIVER_H
#define LIBREVNATCPDRIVER_H
#include "librevnadriver.h"
#include <condition_variable>
#include <thread>
#include <deque>
#include <QQueue>
#include <QTimer>
#include <QUdpSocket>
#include <QTcpSocket>
#include <QDateTime>
class LibreVNATCPDriver : public LibreVNADriver
{
Q_OBJECT
public:
LibreVNATCPDriver();
/**
* @brief Returns the driver name. It must be unique across all implemented drivers and is used to identify the driver
* @return driver name
*/
virtual QString getDriverName() override;
/**
* @brief Lists all available devices by their serial numbers
* @return Serial numbers of detected devices
*/
virtual std::set<QString> GetAvailableDevices() override;
/**
* @brief Connects to a device, given by its serial number
* @param serial Serial number of device that should be connected to
* @return true if connection successful, otherwise false
*/
virtual bool connectTo(QString serial) override;
/**
* @brief Disconnects from device. Has no effect if no device was connected
*/
virtual void disconnect() override;
/**
* @brief Registers metatypes within the Qt Framework.
*
* If the device driver uses a queued signal/slot connection with custom data types, these types must be registered before emitting the signal.
* Register them within this function with qRegisterMetaType<Type>("Name");
*/
virtual void registerTypes();
private slots:
void SSDPreceived(QUdpSocket *sock);
void ReceivedData();
void ReceivedLog();
void transmissionTimeout() {
transmissionFinished(TransmissionResult::Timeout);
}
void transmissionFinished(TransmissionResult result);
private:
static constexpr int EP_Data_Out_Addr = 0x01;
static constexpr int EP_Data_In_Addr = 0x81;
static constexpr int EP_Log_In_Addr = 0x82;
virtual bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500) override;
// Sockets for SSDP protocol
std::vector<QUdpSocket*> ssdpSockets;
class DetectedDevice {
public:
QString serial;
QHostAddress address;
QDateTime responseTime;
int maxAgeSeconds;
};
void addDetectedDevice(const DetectedDevice &d);
// removes entries that are too old
void pruneDetectedDevices();
std::vector<DetectedDevice> detectedDevices;
// Connection sockets
QTcpSocket dataSocket;
QTcpSocket logSocket;
QByteArray dataBuffer;
QByteArray logBuffer;
class Transmission {
public:
Protocol::PacketInfo packet;
unsigned int timeout;
std::function<void(TransmissionResult)> callback;
};
std::mutex transmissionMutex;
QQueue<Transmission> transmissionQueue;
bool startNextTransmission();
QTimer transmissionTimer;
bool transmissionActive;
std::thread *m_receiveThread;
std::mutex accessMutex;
};
#endif // LibreVNATCPDriver_H

View File

@ -249,12 +249,6 @@ void LibreVNAUSBDriver::disconnect()
} }
} }
void LibreVNAUSBDriver::registerTypes()
{
qDebug() << "Registering meta type: " << qRegisterMetaType<Protocol::PacketInfo>();
qDebug() << "Registering meta type: " << qRegisterMetaType<TransmissionResult>();
}
void LibreVNAUSBDriver::ReceivedData() void LibreVNAUSBDriver::ReceivedData()
{ {
Protocol::PacketInfo packet; Protocol::PacketInfo packet;

View File

@ -10,9 +10,6 @@
#include <QQueue> #include <QQueue>
#include <QTimer> #include <QTimer>
Q_DECLARE_METATYPE(Protocol::PacketInfo)
Q_DECLARE_METATYPE(LibreVNADriver::TransmissionResult)
class USBInBuffer : public QObject { class USBInBuffer : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -66,14 +63,6 @@ public:
*/ */
virtual void disconnect() override; virtual void disconnect() override;
/**
* @brief Registers metatypes within the Qt Framework.
*
* If the device driver uses a queued signal/slot connection with custom data types, these types must be registered before emitting the signal.
* Register them within this function with qRegisterMetaType<Type>("Name");
*/
virtual void registerTypes();
private slots: private slots:
void ReceivedData(); void ReceivedData();
void ReceivedLog(); void ReceivedLog();

View File

@ -1,4 +1,4 @@
#include "devicedriver.h" #include "devicedriver.h"
DeviceDriver *DeviceDriver::activeDriver = nullptr; DeviceDriver *DeviceDriver::activeDriver = nullptr;

View File

@ -320,7 +320,7 @@ public:
class SAMeasurement { class SAMeasurement {
public: public:
// Number of point in the sweep // Number of point in the sweep
int pointNum; unsigned int pointNum;
union { union {
struct { struct {
// for non-zero span // for non-zero span

View File

@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>USB Log</string> <string>Device Log</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@ -19,6 +19,11 @@
<property name="headerHidden"> <property name="headerHidden">
<bool>false</bool> <bool>false</bool>
</property> </property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item> <item>

View File

@ -23,6 +23,7 @@ HEADERS += \
Device/LibreVNA/firmwareupdatedialog.h \ Device/LibreVNA/firmwareupdatedialog.h \
Device/LibreVNA/frequencycaldialog.h \ Device/LibreVNA/frequencycaldialog.h \
Device/LibreVNA/librevnadriver.h \ Device/LibreVNA/librevnadriver.h \
Device/LibreVNA/librevnatcpdriver.h \
Device/LibreVNA/librevnausbdriver.h \ Device/LibreVNA/librevnausbdriver.h \
Device/LibreVNA/manualcontroldialog.h \ Device/LibreVNA/manualcontroldialog.h \
Device/LibreVNA/receivercaldialog.h \ Device/LibreVNA/receivercaldialog.h \
@ -174,6 +175,7 @@ SOURCES += \
Device/LibreVNA/firmwareupdatedialog.cpp \ Device/LibreVNA/firmwareupdatedialog.cpp \
Device/LibreVNA/frequencycaldialog.cpp \ Device/LibreVNA/frequencycaldialog.cpp \
Device/LibreVNA/librevnadriver.cpp \ Device/LibreVNA/librevnadriver.cpp \
Device/LibreVNA/librevnatcpdriver.cpp \
Device/LibreVNA/librevnausbdriver.cpp \ Device/LibreVNA/librevnausbdriver.cpp \
Device/LibreVNA/manualcontroldialog.cpp \ Device/LibreVNA/manualcontroldialog.cpp \
Device/LibreVNA/receivercaldialog.cpp \ Device/LibreVNA/receivercaldialog.cpp \

View File

@ -527,7 +527,7 @@ void SpectrumAnalyzer::NewDatapoint(DeviceDriver::SAMeasurement m)
UpdateAverageCount(); UpdateAverageCount();
markerModel->updateMarkers(); markerModel->updateMarkers();
} }
static int lastPoint = 0; static unsigned int lastPoint = 0;
if(m_avg.pointNum > 0 && m_avg.pointNum != lastPoint + 1) { if(m_avg.pointNum > 0 && m_avg.pointNum != lastPoint + 1) {
qWarning() << "Got point" << m_avg.pointNum << "but last received point was" << lastPoint << "("<<(m_avg.pointNum-lastPoint-1)<<"missed points)"; qWarning() << "Got point" << m_avg.pointNum << "but last received point was" << lastPoint << "("<<(m_avg.pointNum-lastPoint-1)<<"missed points)";
} }

View File

@ -8,6 +8,44 @@
#include <QColor> #include <QColor>
#include <QPoint> #include <QPoint>
#include <QEventLoop>
#include <QTimer>
class SynSleep: public QObject {
Q_OBJECT
public:
SynSleep(){
needRunning=1;
}
public slots:
void sleep(){
if (needRunning==1)
loop.exec();
}
void reset(){
needRunning=1;
}
virtual void finish(){
needRunning=0;
loop.exit();
}
static void sleep(int ms) {
QTimer tim;
tim.setSingleShot(true);
auto ss = SynSleep();
connect(&tim, &QTimer::timeout, &ss, &SynSleep::finish);
tim.start(ms);
ss.sleep();
}
private:
QEventLoop loop;
int needRunning;
};
namespace Util { namespace Util {
template<typename T> T Scale(T value, T from_low, T from_high, T to_low, T to_high, bool log_from = false, bool log_to = false) { template<typename T> T Scale(T value, T from_low, T from_high, T to_low, T to_high, bool log_from = false, bool log_to = false) {

View File

@ -26,6 +26,7 @@
#include "modehandler.h" #include "modehandler.h"
#include "modewindow.h" #include "modewindow.h"
#include "Device/LibreVNA/librevnausbdriver.h" #include "Device/LibreVNA/librevnausbdriver.h"
#include "Device/LibreVNA/librevnatcpdriver.h"
#include <QDockWidget> #include <QDockWidget>
#include <QDesktopWidget> #include <QDesktopWidget>
@ -101,6 +102,7 @@ AppWindow::AppWindow(QWidget *parent)
// Register device drivers // Register device drivers
deviceDrivers.push_back(new LibreVNAUSBDriver()); deviceDrivers.push_back(new LibreVNAUSBDriver());
deviceDrivers.push_back(new LibreVNATCPDriver());
for(auto driver : deviceDrivers) { for(auto driver : deviceDrivers) {
driver->registerTypes(); driver->registerTypes();
@ -240,7 +242,7 @@ void AppWindow::SetupMenu()
}); });
// connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl); // connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
connect(ui->actionUSB_log, &QAction::triggered, this, &AppWindow::ShowUSBLog); connect(ui->actionDevice_log, &QAction::triggered, this, &AppWindow::ShowDeviceLog);
// connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog); // connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
// connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog); // connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
// connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog); // connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
@ -369,12 +371,13 @@ bool AppWindow::ConnectToDevice(QString serial, DeviceDriver *driver)
connect(device, &DeviceDriver::LogLineReceived, &deviceLog, &DeviceLog::addLine); connect(device, &DeviceDriver::LogLineReceived, &deviceLog, &DeviceLog::addLine);
connect(device, &DeviceDriver::ConnectionLost, this, &AppWindow::DeviceConnectionLost); connect(device, &DeviceDriver::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
connect(device, &DeviceDriver::StatusUpdated, this, &AppWindow::DeviceStatusUpdated); connect(device, &DeviceDriver::StatusUpdated, this, &AppWindow::DeviceStatusUpdated);
connect(device, &DeviceDriver::releaseControl, [=](){ connect(device, &DeviceDriver::FlagsUpdated, this, &AppWindow::DeviceFlagsUpdated);
connect(device, &DeviceDriver::releaseControl, this, [=](){
if(lastActiveMode) { if(lastActiveMode) {
modeHandler->activate(lastActiveMode); modeHandler->activate(lastActiveMode);
} }
}); });
connect(device, &DeviceDriver::acquireControl, [=](){ connect(device, &DeviceDriver::acquireControl, this, [=](){
lastActiveMode = modeHandler->getActiveMode(); lastActiveMode = modeHandler->getActiveMode();
modeHandler->deactivate(lastActiveMode); modeHandler->deactivate(lastActiveMode);
}); });
@ -440,6 +443,8 @@ void AppWindow::DisconnectDevice()
ui->menuDevice->removeAction(a); ui->menuDevice->removeAction(a);
} }
device->disconnectDevice(); device->disconnectDevice();
disconnect(device, nullptr, &deviceLog, nullptr);
disconnect(device, nullptr, this, nullptr);
device = nullptr; device = nullptr;
} }
ui->actionDisconnect->setEnabled(false); ui->actionDisconnect->setEnabled(false);
@ -465,7 +470,7 @@ void AppWindow::DisconnectDevice()
void AppWindow::DeviceConnectionLost() void AppWindow::DeviceConnectionLost()
{ {
DisconnectDevice(); DisconnectDevice();
InformationBox::ShowError("Disconnected", "The USB connection to the device has been lost"); InformationBox::ShowError("Disconnected", "The connection to the device has been lost");
UpdateDeviceList(); UpdateDeviceList();
} }
@ -1084,7 +1089,7 @@ void AppWindow::UpdateReference()
device->setExtRef(toolbars.reference.type->currentText(), toolbars.reference.outFreq->currentText()); device->setExtRef(toolbars.reference.type->currentText(), toolbars.reference.outFreq->currentText());
} }
void AppWindow::ShowUSBLog() void AppWindow::ShowDeviceLog()
{ {
auto d = new DeviceUSBLogView(); auto d = new DeviceUSBLogView();
if(AppWindow::showGUI()) { if(AppWindow::showGUI()) {

View File

@ -66,7 +66,7 @@ private slots:
void UpdateReferenceToolbar(); void UpdateReferenceToolbar();
void UpdateReference(); void UpdateReference();
// void UpdateAcquisitionFrequencies(); // void UpdateAcquisitionFrequencies();
void ShowUSBLog(); void ShowDeviceLog();
// void StartFirmwareUpdateDialog(); // void StartFirmwareUpdateDialog();
// void DeviceNeedsUpdate(int reported, int expected); // void DeviceNeedsUpdate(int reported, int expected);
void DeviceStatusUpdated(); void DeviceStatusUpdated();

View File

@ -50,7 +50,7 @@
<addaction name="actionDisconnect"/> <addaction name="actionDisconnect"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionUSB_log"/> <addaction name="actionDevice_log"/>
</widget> </widget>
<widget class="QMenu" name="menuWindow"> <widget class="QMenu" name="menuWindow">
<property name="title"> <property name="title">
@ -221,12 +221,12 @@
<string>Preset</string> <string>Preset</string>
</property> </property>
</action> </action>
<action name="actionUSB_log"> <action name="actionDevice_log">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>View USB log</string> <string>View Device Log</string>
</property> </property>
</action> </action>
<action name="actionCreate_Debug_Data"> <action name="actionCreate_Debug_Data">

View File

@ -29,6 +29,7 @@ SOURCES += \
../LibreVNA-GUI/Device/LibreVNA/firmwareupdatedialog.cpp \ ../LibreVNA-GUI/Device/LibreVNA/firmwareupdatedialog.cpp \
../LibreVNA-GUI/Device/LibreVNA/frequencycaldialog.cpp \ ../LibreVNA-GUI/Device/LibreVNA/frequencycaldialog.cpp \
../LibreVNA-GUI/Device/LibreVNA/librevnadriver.cpp \ ../LibreVNA-GUI/Device/LibreVNA/librevnadriver.cpp \
../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp \
../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp \ ../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialog.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialog.cpp \
../LibreVNA-GUI/Device/LibreVNA/receivercaldialog.cpp \ ../LibreVNA-GUI/Device/LibreVNA/receivercaldialog.cpp \
@ -199,6 +200,7 @@ HEADERS += \
../LibreVNA-GUI/Device/LibreVNA/firmwareupdatedialog.h \ ../LibreVNA-GUI/Device/LibreVNA/firmwareupdatedialog.h \
../LibreVNA-GUI/Device/LibreVNA/frequencycaldialog.h \ ../LibreVNA-GUI/Device/LibreVNA/frequencycaldialog.h \
../LibreVNA-GUI/Device/LibreVNA/librevnadriver.h \ ../LibreVNA-GUI/Device/LibreVNA/librevnadriver.h \
../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.h \
../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.h \ ../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.h \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialog.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialog.h \
../LibreVNA-GUI/Device/LibreVNA/receivercaldialog.h \ ../LibreVNA-GUI/Device/LibreVNA/receivercaldialog.h \