mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 21:20:31 -05:00 
			
		
		
		
	Add basic support for KiwiSDR receivers
This commit is contained in:
		
							parent
							
								
									ef32417245
								
							
						
					
					
						commit
						779f3fdb16
					
				@ -291,6 +291,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
 | 
			
		||||
set(_required_qt_version "5.6.0")
 | 
			
		||||
find_package(Qt5 COMPONENTS Core REQUIRED)
 | 
			
		||||
find_package(Qt5 COMPONENTS Widgets REQUIRED)
 | 
			
		||||
find_package(Qt5 COMPONENTS WebSockets REQUIRED)
 | 
			
		||||
find_package(Qt5 COMPONENTS Multimedia REQUIRED)
 | 
			
		||||
find_package(Qt5 COMPONENTS MultimediaWidgets REQUIRED)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -58,3 +58,4 @@ if(ENABLE_SOAPYSDR AND SOAPYSDR_FOUND)
 | 
			
		||||
    add_subdirectory(soapysdrinput)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_subdirectory(kiwisdr)
 | 
			
		||||
							
								
								
									
										56
									
								
								plugins/samplesource/kiwisdr/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								plugins/samplesource/kiwisdr/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
project(kiwisdr)
 | 
			
		||||
 | 
			
		||||
set(kiwisdr_SOURCES
 | 
			
		||||
	kiwisdrinput.cpp
 | 
			
		||||
	kiwisdrplugin.cpp
 | 
			
		||||
	kiwisdrworker.cpp
 | 
			
		||||
	kiwisdrsettings.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(kiwisdr_HEADERS
 | 
			
		||||
	kiwisdrinput.h
 | 
			
		||||
	kiwisdrplugin.h
 | 
			
		||||
	kiwisdrworker.h
 | 
			
		||||
	kiwisdrsettings.h
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
include_directories(
 | 
			
		||||
	${Boost_INCLUDE_DIRS}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if(NOT SERVER_MODE)
 | 
			
		||||
    set(kiwisdr_SOURCES
 | 
			
		||||
        ${kiwisdr_SOURCES}
 | 
			
		||||
        kiwisdrgui.cpp
 | 
			
		||||
 | 
			
		||||
        kiwisdrgui.ui
 | 
			
		||||
    )
 | 
			
		||||
    set(kiwisdr_HEADERS
 | 
			
		||||
        ${kiwisdr_HEADERS}
 | 
			
		||||
        kiwisdrgui.h
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
	set(TARGET_NAME inputkiwisdr)
 | 
			
		||||
	set(TARGET_LIB "Qt5::Widgets")
 | 
			
		||||
	set(TARGET_LIB_GUI "sdrgui")
 | 
			
		||||
	set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
 | 
			
		||||
else()
 | 
			
		||||
    set(TARGET_NAME inputkiwisdrsrv)
 | 
			
		||||
    set(TARGET_LIB "")
 | 
			
		||||
    set(TARGET_LIB_GUI "")
 | 
			
		||||
    set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_library(${TARGET_NAME} SHARED
 | 
			
		||||
	${kiwisdr_SOURCES}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(${TARGET_NAME}
 | 
			
		||||
	Qt5::Core
 | 
			
		||||
	Qt5::WebSockets
 | 
			
		||||
	${TARGET_LIB}
 | 
			
		||||
	sdrbase
 | 
			
		||||
	${TARGET_LIB_GUI}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
 | 
			
		||||
							
								
								
									
										339
									
								
								plugins/samplesource/kiwisdr/kiwisdrgui.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								plugins/samplesource/kiwisdr/kiwisdrgui.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,339 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
#include <QTime>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
#include "ui_kiwisdrgui.h"
 | 
			
		||||
#include "plugin/pluginapi.h"
 | 
			
		||||
#include "gui/colormapper.h"
 | 
			
		||||
#include "gui/glspectrum.h"
 | 
			
		||||
#include "gui/crightclickenabler.h"
 | 
			
		||||
#include "gui/basicdevicesettingsdialog.h"
 | 
			
		||||
#include "dsp/dspengine.h"
 | 
			
		||||
#include "dsp/dspcommands.h"
 | 
			
		||||
#include "util/db.h"
 | 
			
		||||
 | 
			
		||||
#include "mainwindow.h"
 | 
			
		||||
 | 
			
		||||
#include "kiwisdrgui.h"
 | 
			
		||||
#include "device/deviceapi.h"
 | 
			
		||||
#include "device/deviceuiset.h"
 | 
			
		||||
 | 
			
		||||
KiwiSDRGui::KiwiSDRGui(DeviceUISet *deviceUISet, QWidget* parent) :
 | 
			
		||||
    QWidget(parent),
 | 
			
		||||
    ui(new Ui::KiwiSDRGui),
 | 
			
		||||
    m_deviceUISet(deviceUISet),
 | 
			
		||||
    m_settings(),
 | 
			
		||||
    m_doApplySettings(true),
 | 
			
		||||
    m_forceSettings(true),
 | 
			
		||||
    m_sampleSource(0),
 | 
			
		||||
    m_tickCount(0),
 | 
			
		||||
    m_lastEngineState(DeviceAPI::StNotStarted)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("KiwiSDRGui::KiwiSDRGui");
 | 
			
		||||
    m_sampleSource = m_deviceUISet->m_deviceAPI->getSampleSource();
 | 
			
		||||
 | 
			
		||||
	m_statusTooltips.push_back("Idle");
 | 
			
		||||
	m_statusTooltips.push_back("Connecting...");
 | 
			
		||||
	m_statusTooltips.push_back("Connected");
 | 
			
		||||
	m_statusTooltips.push_back("Error");
 | 
			
		||||
 | 
			
		||||
	m_statusColors.push_back("gray");
 | 
			
		||||
	m_statusColors.push_back("rgb(232, 212, 35)");
 | 
			
		||||
	m_statusColors.push_back("rgb(35, 138, 35)");
 | 
			
		||||
	m_statusColors.push_back("rgb(232, 85, 85)");
 | 
			
		||||
 | 
			
		||||
    ui->setupUi(this);
 | 
			
		||||
    ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
 | 
			
		||||
    ui->centerFrequency->setValueRange(7, 0, 9999999);
 | 
			
		||||
 | 
			
		||||
    displaySettings();
 | 
			
		||||
 | 
			
		||||
    connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
 | 
			
		||||
    connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
 | 
			
		||||
    m_statusTimer.start(500);
 | 
			
		||||
 | 
			
		||||
    connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
 | 
			
		||||
    m_sampleSource->setMessageQueueToGUI(&m_inputMessageQueue);
 | 
			
		||||
 | 
			
		||||
    CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
 | 
			
		||||
    connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KiwiSDRGui::~KiwiSDRGui()
 | 
			
		||||
{
 | 
			
		||||
    delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::destroy()
 | 
			
		||||
{
 | 
			
		||||
    delete this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::setName(const QString& name)
 | 
			
		||||
{
 | 
			
		||||
    setObjectName(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString KiwiSDRGui::getName() const
 | 
			
		||||
{
 | 
			
		||||
    return objectName();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::resetToDefaults()
 | 
			
		||||
{
 | 
			
		||||
    m_settings.resetToDefaults();
 | 
			
		||||
    displaySettings();
 | 
			
		||||
    sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qint64 KiwiSDRGui::getCenterFrequency() const
 | 
			
		||||
{
 | 
			
		||||
    return m_settings.m_centerFrequency;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::setCenterFrequency(qint64 centerFrequency)
 | 
			
		||||
{
 | 
			
		||||
    m_settings.m_centerFrequency = centerFrequency;
 | 
			
		||||
    displaySettings();
 | 
			
		||||
    sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray KiwiSDRGui::serialize() const
 | 
			
		||||
{
 | 
			
		||||
    return m_settings.serialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRGui::deserialize(const QByteArray& data)
 | 
			
		||||
{
 | 
			
		||||
    if(m_settings.deserialize(data)) {
 | 
			
		||||
        displaySettings();
 | 
			
		||||
        m_forceSettings = true;
 | 
			
		||||
        sendSettings();
 | 
			
		||||
        return true;
 | 
			
		||||
    } else {
 | 
			
		||||
        resetToDefaults();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_startStop_toggled(bool checked)
 | 
			
		||||
{
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
		KiwiSDRInput::MsgStartStop *message = KiwiSDRInput::MsgStartStop::create(checked);
 | 
			
		||||
        m_sampleSource->getInputMessageQueue()->push(message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_centerFrequency_changed(quint64 value)
 | 
			
		||||
{
 | 
			
		||||
    m_settings.m_centerFrequency = value * 1000;
 | 
			
		||||
    sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_serverAddress_returnPressed()
 | 
			
		||||
{
 | 
			
		||||
	on_serverAddressApplyButton_clicked();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_serverAddressApplyButton_clicked()
 | 
			
		||||
{
 | 
			
		||||
	m_settings.m_serverAddress = ui->serverAddress->text();
 | 
			
		||||
	sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_record_toggled(bool checked)
 | 
			
		||||
{
 | 
			
		||||
    if (checked) {
 | 
			
		||||
        ui->record->setStyleSheet("QToolButton { background-color : red; }");
 | 
			
		||||
    } else {
 | 
			
		||||
        ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	KiwiSDRInput::MsgFileRecord* message = KiwiSDRInput::MsgFileRecord::create(checked);
 | 
			
		||||
    m_sampleSource->getInputMessageQueue()->push(message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_agc_toggled(bool checked)
 | 
			
		||||
{
 | 
			
		||||
	m_settings.m_useAGC = checked;
 | 
			
		||||
	sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::on_gain_valueChanged(int value)
 | 
			
		||||
{
 | 
			
		||||
	m_settings.m_gain = value;
 | 
			
		||||
	ui->gainText->setText(QString::number(m_settings.m_gain) + " dB");
 | 
			
		||||
	sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::displaySettings()
 | 
			
		||||
{
 | 
			
		||||
    blockApplySettings(true);
 | 
			
		||||
 | 
			
		||||
    ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
 | 
			
		||||
	ui->serverAddress->setText(m_settings.m_serverAddress);
 | 
			
		||||
	ui->gain->setValue(m_settings.m_gain);
 | 
			
		||||
	ui->gainText->setText(QString::number(m_settings.m_gain) + " dB");
 | 
			
		||||
	ui->agc->setChecked(m_settings.m_useAGC);
 | 
			
		||||
 | 
			
		||||
    blockApplySettings(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::sendSettings()
 | 
			
		||||
{
 | 
			
		||||
    if (!m_updateTimer.isActive()) {
 | 
			
		||||
        m_updateTimer.start(100);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::updateHardware()
 | 
			
		||||
{
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
		KiwiSDRInput::MsgConfigureKiwiSDR* message = KiwiSDRInput::MsgConfigureKiwiSDR::create(m_settings, m_forceSettings);
 | 
			
		||||
        m_sampleSource->getInputMessageQueue()->push(message);
 | 
			
		||||
        m_forceSettings = false;
 | 
			
		||||
        m_updateTimer.stop();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::updateStatus()
 | 
			
		||||
{
 | 
			
		||||
    int state = m_deviceUISet->m_deviceAPI->state();
 | 
			
		||||
 | 
			
		||||
    if (m_lastEngineState != state)
 | 
			
		||||
    {
 | 
			
		||||
        switch (state)
 | 
			
		||||
        {
 | 
			
		||||
            case DeviceAPI::StNotStarted:
 | 
			
		||||
                ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
 | 
			
		||||
                break;
 | 
			
		||||
            case DeviceAPI::StIdle:
 | 
			
		||||
                ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
 | 
			
		||||
                break;
 | 
			
		||||
            case DeviceAPI::StRunning:
 | 
			
		||||
                ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
 | 
			
		||||
                break;
 | 
			
		||||
            case DeviceAPI::StError:
 | 
			
		||||
                ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
 | 
			
		||||
                QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_lastEngineState = state;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRGui::handleMessage(const Message& message)
 | 
			
		||||
{
 | 
			
		||||
    if (KiwiSDRInput::MsgConfigureKiwiSDR::match(message))
 | 
			
		||||
    {
 | 
			
		||||
        qDebug("KiwiSDRGui::handleMessage: MsgConfigureKiwiSDR");
 | 
			
		||||
        const KiwiSDRInput::MsgConfigureKiwiSDR& cfg = (KiwiSDRInput::MsgConfigureKiwiSDR&) message;
 | 
			
		||||
        m_settings = cfg.getSettings();
 | 
			
		||||
        displaySettings();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else if (KiwiSDRInput::MsgStartStop::match(message))
 | 
			
		||||
    {
 | 
			
		||||
        qDebug("KiwiSDRGui::handleMessage: MsgStartStop");
 | 
			
		||||
		KiwiSDRInput::MsgStartStop& notif = (KiwiSDRInput::MsgStartStop&) message;
 | 
			
		||||
        blockApplySettings(true);
 | 
			
		||||
        ui->startStop->setChecked(notif.getStartStop());
 | 
			
		||||
        blockApplySettings(false);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
	else if (KiwiSDRInput::MsgSetStatus::match(message))
 | 
			
		||||
	{
 | 
			
		||||
		qDebug("KiwiSDRGui::handleMessage: MsgSetStatus");
 | 
			
		||||
		KiwiSDRInput::MsgSetStatus& notif = (KiwiSDRInput::MsgSetStatus&) message;
 | 
			
		||||
		int status = notif.getStatus();
 | 
			
		||||
		ui->statusIndicator->setToolTip(m_statusTooltips[status]);
 | 
			
		||||
		ui->statusIndicator->setStyleSheet("QLabel { background-color: " +
 | 
			
		||||
			m_statusColors[status] + "; border-radius: 7px; }");
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::handleInputMessages()
 | 
			
		||||
{
 | 
			
		||||
    Message* message;
 | 
			
		||||
 | 
			
		||||
    while ((message = m_inputMessageQueue.pop()) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (DSPSignalNotification::match(*message))
 | 
			
		||||
        {
 | 
			
		||||
            DSPSignalNotification* notif = (DSPSignalNotification*) message;
 | 
			
		||||
            m_deviceSampleRate = notif->getSampleRate();
 | 
			
		||||
            m_deviceCenterFrequency = notif->getCenterFrequency();
 | 
			
		||||
            qDebug("KiwiSDRGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu",
 | 
			
		||||
                    notif->getSampleRate(),
 | 
			
		||||
                    notif->getCenterFrequency());
 | 
			
		||||
            updateSampleRateAndFrequency();
 | 
			
		||||
 | 
			
		||||
            delete message;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (handleMessage(*message))
 | 
			
		||||
            {
 | 
			
		||||
                delete message;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::updateSampleRateAndFrequency()
 | 
			
		||||
{
 | 
			
		||||
    m_deviceUISet->getSpectrum()->setSampleRate(m_deviceSampleRate);
 | 
			
		||||
    m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency);
 | 
			
		||||
    ui->deviceRateText->setText(tr("%1k").arg((float)m_deviceSampleRate / 1000));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRGui::openDeviceSettingsDialog(const QPoint& p)
 | 
			
		||||
{
 | 
			
		||||
    BasicDeviceSettingsDialog dialog(this);
 | 
			
		||||
    dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
 | 
			
		||||
    dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
 | 
			
		||||
    dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
 | 
			
		||||
    dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
 | 
			
		||||
 | 
			
		||||
    dialog.move(p);
 | 
			
		||||
    dialog.exec();
 | 
			
		||||
 | 
			
		||||
    m_settings.m_useReverseAPI = dialog.useReverseAPI();
 | 
			
		||||
    m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
 | 
			
		||||
    m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
 | 
			
		||||
    m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
 | 
			
		||||
 | 
			
		||||
    sendSettings();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								plugins/samplesource/kiwisdr/kiwisdrgui.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								plugins/samplesource/kiwisdr/kiwisdrgui.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef _KIWISDR_KIWISDRGUI_H_
 | 
			
		||||
#define _KIWISDR_KIWISDRGUI_H_
 | 
			
		||||
 | 
			
		||||
#include <plugin/plugininstancegui.h>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
#include "util/messagequeue.h"
 | 
			
		||||
 | 
			
		||||
#include "kiwisdrsettings.h"
 | 
			
		||||
#include "kiwisdrinput.h"
 | 
			
		||||
 | 
			
		||||
class DeviceUISet;
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
	class KiwiSDRGui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class KiwiSDRGui : public QWidget, public PluginInstanceGUI {
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	explicit KiwiSDRGui(DeviceUISet *deviceUISet, QWidget* parent = 0);
 | 
			
		||||
	virtual ~KiwiSDRGui();
 | 
			
		||||
	virtual void destroy();
 | 
			
		||||
 | 
			
		||||
	void setName(const QString& name);
 | 
			
		||||
	QString getName() const;
 | 
			
		||||
 | 
			
		||||
	void resetToDefaults();
 | 
			
		||||
	virtual qint64 getCenterFrequency() const;
 | 
			
		||||
	virtual void setCenterFrequency(qint64 centerFrequency);
 | 
			
		||||
	QByteArray serialize() const;
 | 
			
		||||
	bool deserialize(const QByteArray& data);
 | 
			
		||||
	virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
 | 
			
		||||
	virtual bool handleMessage(const Message& message);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	Ui::KiwiSDRGui* ui;
 | 
			
		||||
 | 
			
		||||
	DeviceUISet* m_deviceUISet;
 | 
			
		||||
	KiwiSDRSettings m_settings;
 | 
			
		||||
    QTimer m_updateTimer;
 | 
			
		||||
    QTimer m_statusTimer;
 | 
			
		||||
	bool m_doApplySettings;
 | 
			
		||||
    bool m_forceSettings;
 | 
			
		||||
	DeviceSampleSource* m_sampleSource;
 | 
			
		||||
	std::size_t m_tickCount;
 | 
			
		||||
    int m_deviceSampleRate;
 | 
			
		||||
    quint64 m_deviceCenterFrequency; //!< Center frequency in device
 | 
			
		||||
	int m_lastEngineState;
 | 
			
		||||
	MessageQueue m_inputMessageQueue;
 | 
			
		||||
	std::vector<QString> m_statusColors;
 | 
			
		||||
	std::vector<QString> m_statusTooltips;
 | 
			
		||||
 | 
			
		||||
	void blockApplySettings(bool block) { m_doApplySettings = !block; }
 | 
			
		||||
	void displaySettings();
 | 
			
		||||
	void sendSettings();
 | 
			
		||||
    void updateSampleRateAndFrequency();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void handleInputMessages();
 | 
			
		||||
	void on_startStop_toggled(bool checked);
 | 
			
		||||
    void on_centerFrequency_changed(quint64 value);
 | 
			
		||||
	void on_record_toggled(bool checked);
 | 
			
		||||
	void on_gain_valueChanged(int value);
 | 
			
		||||
	void on_agc_toggled(bool checked);
 | 
			
		||||
	void on_serverAddress_returnPressed();
 | 
			
		||||
	void on_serverAddressApplyButton_clicked();
 | 
			
		||||
	void openDeviceSettingsDialog(const QPoint& p);
 | 
			
		||||
    void updateStatus();
 | 
			
		||||
    void updateHardware();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _KIWISDR_KIWISDRGUI_H_
 | 
			
		||||
							
								
								
									
										347
									
								
								plugins/samplesource/kiwisdr/kiwisdrgui.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								plugins/samplesource/kiwisdr/kiwisdrgui.ui
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,347 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>KiwiSDRGui</class>
 | 
			
		||||
 <widget class="QWidget" name="KiwiSDRGui">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>360</width>
 | 
			
		||||
    <height>120</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="sizePolicy">
 | 
			
		||||
   <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
 | 
			
		||||
    <horstretch>0</horstretch>
 | 
			
		||||
    <verstretch>0</verstretch>
 | 
			
		||||
   </sizepolicy>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="minimumSize">
 | 
			
		||||
   <size>
 | 
			
		||||
    <width>360</width>
 | 
			
		||||
    <height>120</height>
 | 
			
		||||
   </size>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="font">
 | 
			
		||||
   <font>
 | 
			
		||||
    <family>Liberation Sans</family>
 | 
			
		||||
    <pointsize>9</pointsize>
 | 
			
		||||
    <weight>50</weight>
 | 
			
		||||
    <italic>false</italic>
 | 
			
		||||
    <bold>false</bold>
 | 
			
		||||
   </font>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Test source</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
   <property name="spacing">
 | 
			
		||||
    <number>3</number>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="leftMargin">
 | 
			
		||||
    <number>2</number>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="topMargin">
 | 
			
		||||
    <number>2</number>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="rightMargin">
 | 
			
		||||
    <number>2</number>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="bottomMargin">
 | 
			
		||||
    <number>2</number>
 | 
			
		||||
   </property>
 | 
			
		||||
   <item>
 | 
			
		||||
    <layout class="QHBoxLayout" name="horizontalLayout_freq">
 | 
			
		||||
     <property name="topMargin">
 | 
			
		||||
      <number>4</number>
 | 
			
		||||
     </property>
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QVBoxLayout" name="deviceUILayout">
 | 
			
		||||
       <item>
 | 
			
		||||
        <layout class="QHBoxLayout" name="deviceButtonsLayout">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="ButtonSwitch" name="startStop">
 | 
			
		||||
           <property name="toolTip">
 | 
			
		||||
            <string>start/stop acquisition</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string/>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="icon">
 | 
			
		||||
            <iconset resource="../../../sdrgui/resources/res.qrc">
 | 
			
		||||
             <normaloff>:/play.png</normaloff>
 | 
			
		||||
             <normalon>:/stop.png</normalon>:/play.png</iconset>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="ButtonSwitch" name="record">
 | 
			
		||||
           <property name="toolTip">
 | 
			
		||||
            <string>Toggle record I/Q samples from device</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string/>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="icon">
 | 
			
		||||
            <iconset resource="../../../sdrgui/resources/res.qrc">
 | 
			
		||||
             <normaloff>:/record_off.png</normaloff>:/record_off.png</iconset>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <layout class="QHBoxLayout" name="deviceRateLayout">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLabel" name="deviceRateText">
 | 
			
		||||
           <property name="minimumSize">
 | 
			
		||||
            <size>
 | 
			
		||||
             <width>58</width>
 | 
			
		||||
             <height>0</height>
 | 
			
		||||
            </size>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="toolTip">
 | 
			
		||||
            <string>I/Q sample rate kS/s</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>0000.00k</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <spacer name="horizontalSpacer">
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Horizontal</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeHint" stdset="0">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>0</width>
 | 
			
		||||
         <height>0</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
      </spacer>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="ValueDial" name="centerFrequency" native="true">
 | 
			
		||||
       <property name="sizePolicy">
 | 
			
		||||
        <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
 | 
			
		||||
         <horstretch>0</horstretch>
 | 
			
		||||
         <verstretch>0</verstretch>
 | 
			
		||||
        </sizepolicy>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>32</width>
 | 
			
		||||
         <height>16</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="font">
 | 
			
		||||
        <font>
 | 
			
		||||
         <family>Liberation Mono</family>
 | 
			
		||||
         <pointsize>20</pointsize>
 | 
			
		||||
        </font>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="cursor">
 | 
			
		||||
        <cursorShape>PointingHandCursor</cursorShape>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="focusPolicy">
 | 
			
		||||
        <enum>Qt::StrongFocus</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="toolTip">
 | 
			
		||||
        <string>Tuner center frequency in kHz</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="freqUnits">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string> kHz</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <spacer name="horizontalSpacer_2">
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Horizontal</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeHint" stdset="0">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>0</width>
 | 
			
		||||
         <height>0</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
      </spacer>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="Line" name="line_2">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Horizontal</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <layout class="QHBoxLayout" name="serverAddressLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="serverAddressLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Addr</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLineEdit" name="serverAddress">
 | 
			
		||||
       <property name="toolTip">
 | 
			
		||||
        <string>Server address</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>127.0.0.1:8073</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="statusIndicator">
 | 
			
		||||
       <property name="sizePolicy">
 | 
			
		||||
        <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
 | 
			
		||||
         <horstretch>0</horstretch>
 | 
			
		||||
         <verstretch>0</verstretch>
 | 
			
		||||
        </sizepolicy>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>14</width>
 | 
			
		||||
         <height>14</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="toolTip">
 | 
			
		||||
        <string>Idle</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="styleSheet">
 | 
			
		||||
        <string notr="true">QLabel { background-color: gray; border-radius: 7px; }</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string/>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QPushButton" name="serverAddressApplyButton">
 | 
			
		||||
       <property name="maximumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>30</width>
 | 
			
		||||
         <height>16777215</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Set</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <layout class="QHBoxLayout" name="gainLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="gainLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Gain</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QSlider" name="gain">
 | 
			
		||||
       <property name="toolTip">
 | 
			
		||||
        <string>Manual gain</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="maximum">
 | 
			
		||||
        <number>120</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="pageStep">
 | 
			
		||||
        <number>1</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="value">
 | 
			
		||||
        <number>20</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Horizontal</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="tickPosition">
 | 
			
		||||
        <enum>QSlider::NoTicks</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="gainText">
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>40</width>
 | 
			
		||||
         <height>0</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>20 dB</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QToolButton" name="agc">
 | 
			
		||||
       <property name="toolTip">
 | 
			
		||||
        <string>Automatic gain control</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>AGC</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="checkable">
 | 
			
		||||
        <bool>true</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="checked">
 | 
			
		||||
        <bool>true</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <spacer name="verticalSpacer">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Vertical</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="sizeHint" stdset="0">
 | 
			
		||||
      <size>
 | 
			
		||||
       <width>20</width>
 | 
			
		||||
       <height>40</height>
 | 
			
		||||
      </size>
 | 
			
		||||
     </property>
 | 
			
		||||
    </spacer>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <customwidgets>
 | 
			
		||||
  <customwidget>
 | 
			
		||||
   <class>ValueDial</class>
 | 
			
		||||
   <extends>QWidget</extends>
 | 
			
		||||
   <header>gui/valuedial.h</header>
 | 
			
		||||
   <container>1</container>
 | 
			
		||||
  </customwidget>
 | 
			
		||||
  <customwidget>
 | 
			
		||||
   <class>ButtonSwitch</class>
 | 
			
		||||
   <extends>QToolButton</extends>
 | 
			
		||||
   <header>gui/buttonswitch.h</header>
 | 
			
		||||
  </customwidget>
 | 
			
		||||
 </customwidgets>
 | 
			
		||||
 <resources>
 | 
			
		||||
  <include location="../../../sdrgui/resources/res.qrc"/>
 | 
			
		||||
 </resources>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
							
								
								
									
										348
									
								
								plugins/samplesource/kiwisdr/kiwisdrinput.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								plugins/samplesource/kiwisdr/kiwisdrinput.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,348 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QNetworkAccessManager>
 | 
			
		||||
#include <QBuffer>
 | 
			
		||||
 | 
			
		||||
#include "kiwisdrinput.h"
 | 
			
		||||
#include "device/deviceapi.h"
 | 
			
		||||
#include "kiwisdrworker.h"
 | 
			
		||||
#include "dsp/dspcommands.h"
 | 
			
		||||
#include "dsp/dspengine.h"
 | 
			
		||||
#include "dsp/filerecord.h"
 | 
			
		||||
 | 
			
		||||
MESSAGE_CLASS_DEFINITION(KiwiSDRInput::MsgConfigureKiwiSDR, Message)
 | 
			
		||||
MESSAGE_CLASS_DEFINITION(KiwiSDRInput::MsgFileRecord, Message)
 | 
			
		||||
MESSAGE_CLASS_DEFINITION(KiwiSDRInput::MsgStartStop, Message)
 | 
			
		||||
MESSAGE_CLASS_DEFINITION(KiwiSDRInput::MsgSetStatus, Message)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
KiwiSDRInput::KiwiSDRInput(DeviceAPI *deviceAPI) :
 | 
			
		||||
    m_deviceAPI(deviceAPI),
 | 
			
		||||
	m_settings(),
 | 
			
		||||
	m_kiwiSDRWorker(nullptr),
 | 
			
		||||
	m_deviceDescription(),
 | 
			
		||||
	m_running(false),
 | 
			
		||||
	m_masterTimer(deviceAPI->getMasterTimer())
 | 
			
		||||
{
 | 
			
		||||
	m_kiwiSDRWorkerThread.start();
 | 
			
		||||
 | 
			
		||||
    m_fileSink = new FileRecord();
 | 
			
		||||
    m_deviceAPI->setNbSourceStreams(1);
 | 
			
		||||
    m_deviceAPI->addAncillarySink(m_fileSink);
 | 
			
		||||
 | 
			
		||||
    if (!m_sampleFifo.setSize(getSampleRate() * 2)) {
 | 
			
		||||
        qCritical("KiwiSDRInput::KiwiSDRInput: Could not allocate SampleFifo");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_networkManager = new QNetworkAccessManager();
 | 
			
		||||
    connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KiwiSDRInput::~KiwiSDRInput()
 | 
			
		||||
{
 | 
			
		||||
    disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
 | 
			
		||||
    delete m_networkManager;
 | 
			
		||||
 | 
			
		||||
    if (m_running) {
 | 
			
		||||
        stop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	m_kiwiSDRWorkerThread.quit();
 | 
			
		||||
	m_kiwiSDRWorkerThread.wait();
 | 
			
		||||
 | 
			
		||||
    m_deviceAPI->removeAncillarySink(m_fileSink);
 | 
			
		||||
    delete m_fileSink;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::destroy()
 | 
			
		||||
{
 | 
			
		||||
    delete this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::init()
 | 
			
		||||
{
 | 
			
		||||
    applySettings(m_settings, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRInput::start()
 | 
			
		||||
{
 | 
			
		||||
	QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
 | 
			
		||||
    if (m_running) stop();
 | 
			
		||||
 | 
			
		||||
	m_kiwiSDRWorker = new KiwiSDRWorker(&m_sampleFifo);
 | 
			
		||||
	m_kiwiSDRWorker->moveToThread(&m_kiwiSDRWorkerThread);
 | 
			
		||||
 | 
			
		||||
	connect(this, &KiwiSDRInput::setWorkerCenterFrequency, m_kiwiSDRWorker, &KiwiSDRWorker::onCenterFrequencyChanged);
 | 
			
		||||
	connect(this, &KiwiSDRInput::setWorkerServerAddress, m_kiwiSDRWorker, &KiwiSDRWorker::onServerAddressChanged);
 | 
			
		||||
	connect(this, &KiwiSDRInput::setWorkerGain, m_kiwiSDRWorker, &KiwiSDRWorker::onGainChanged);
 | 
			
		||||
	connect(m_kiwiSDRWorker, &KiwiSDRWorker::updateStatus, this, &KiwiSDRInput::setWorkerStatus);
 | 
			
		||||
 | 
			
		||||
	mutexLocker.unlock();
 | 
			
		||||
 | 
			
		||||
	applySettings(m_settings, true);
 | 
			
		||||
	m_running = true;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::stop()
 | 
			
		||||
{
 | 
			
		||||
	QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
 | 
			
		||||
	setWorkerStatus(0);
 | 
			
		||||
 | 
			
		||||
	if (m_kiwiSDRWorker != 0)
 | 
			
		||||
	{
 | 
			
		||||
		m_kiwiSDRWorker->deleteLater();
 | 
			
		||||
		m_kiwiSDRWorker = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_running = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray KiwiSDRInput::serialize() const
 | 
			
		||||
{
 | 
			
		||||
    return m_settings.serialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRInput::deserialize(const QByteArray& data)
 | 
			
		||||
{
 | 
			
		||||
    bool success = true;
 | 
			
		||||
 | 
			
		||||
    if (!m_settings.deserialize(data))
 | 
			
		||||
    {
 | 
			
		||||
        m_settings.resetToDefaults();
 | 
			
		||||
        success = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MsgConfigureKiwiSDR* message = MsgConfigureKiwiSDR::create(m_settings, true);
 | 
			
		||||
    m_inputMessageQueue.push(message);
 | 
			
		||||
 | 
			
		||||
    if (m_guiMessageQueue)
 | 
			
		||||
    {
 | 
			
		||||
        MsgConfigureKiwiSDR* messageToGUI = MsgConfigureKiwiSDR::create(m_settings, true);
 | 
			
		||||
        m_guiMessageQueue->push(messageToGUI);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const QString& KiwiSDRInput::getDeviceDescription() const
 | 
			
		||||
{
 | 
			
		||||
	return m_deviceDescription;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int KiwiSDRInput::getSampleRate() const
 | 
			
		||||
{
 | 
			
		||||
	return 12000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
quint64 KiwiSDRInput::getCenterFrequency() const
 | 
			
		||||
{
 | 
			
		||||
	return m_settings.m_centerFrequency;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::setCenterFrequency(qint64 centerFrequency)
 | 
			
		||||
{
 | 
			
		||||
	KiwiSDRSettings settings = m_settings;
 | 
			
		||||
    settings.m_centerFrequency = centerFrequency;
 | 
			
		||||
 | 
			
		||||
    MsgConfigureKiwiSDR* message = MsgConfigureKiwiSDR::create(settings, false);
 | 
			
		||||
    m_inputMessageQueue.push(message);
 | 
			
		||||
 | 
			
		||||
    if (m_guiMessageQueue)
 | 
			
		||||
    {
 | 
			
		||||
        MsgConfigureKiwiSDR* messageToGUI = MsgConfigureKiwiSDR::create(settings, false);
 | 
			
		||||
        m_guiMessageQueue->push(messageToGUI);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::setWorkerStatus(int status)
 | 
			
		||||
{
 | 
			
		||||
	if (m_guiMessageQueue)
 | 
			
		||||
		m_guiMessageQueue->push(MsgSetStatus::create(status));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRInput::handleMessage(const Message& message)
 | 
			
		||||
{
 | 
			
		||||
    if (MsgConfigureKiwiSDR::match(message))
 | 
			
		||||
    {
 | 
			
		||||
        MsgConfigureKiwiSDR& conf = (MsgConfigureKiwiSDR&) message;
 | 
			
		||||
        qDebug() << "KiwiSDRInput::handleMessage: MsgConfigureKiwiSDR";
 | 
			
		||||
 | 
			
		||||
        bool success = applySettings(conf.getSettings(), conf.getForce());
 | 
			
		||||
 | 
			
		||||
        if (!success)
 | 
			
		||||
        {
 | 
			
		||||
            qDebug("KiwiSDRInput::handleMessage: config error");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else if (MsgFileRecord::match(message))
 | 
			
		||||
    {
 | 
			
		||||
        MsgFileRecord& conf = (MsgFileRecord&) message;
 | 
			
		||||
        qDebug() << "KiwiSDRInput::handleMessage: MsgFileRecord: " << conf.getStartStop();
 | 
			
		||||
 | 
			
		||||
        if (conf.getStartStop())
 | 
			
		||||
        {
 | 
			
		||||
            m_fileSink->genUniqueFileName(m_deviceAPI->getDeviceUID());
 | 
			
		||||
            m_fileSink->startRecording();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            m_fileSink->stopRecording();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else if (MsgStartStop::match(message))
 | 
			
		||||
    {
 | 
			
		||||
        MsgStartStop& cmd = (MsgStartStop&) message;
 | 
			
		||||
        qDebug() << "KiwiSDRInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
 | 
			
		||||
 | 
			
		||||
        if (cmd.getStartStop())
 | 
			
		||||
        {
 | 
			
		||||
            if (m_deviceAPI->initDeviceEngine())
 | 
			
		||||
            {
 | 
			
		||||
                m_deviceAPI->startDeviceEngine();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            m_deviceAPI->stopDeviceEngine();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (m_settings.m_useReverseAPI) {
 | 
			
		||||
            webapiReverseSendStartStop(cmd.getStartStop());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRInput::applySettings(const KiwiSDRSettings& settings, bool force)
 | 
			
		||||
{
 | 
			
		||||
    QList<QString> reverseAPIKeys;
 | 
			
		||||
 | 
			
		||||
	if (m_settings.m_serverAddress != settings.m_serverAddress || force)
 | 
			
		||||
		emit setWorkerServerAddress(settings.m_serverAddress);
 | 
			
		||||
 | 
			
		||||
	if (m_settings.m_gain != settings.m_gain ||
 | 
			
		||||
		m_settings.m_useAGC != settings.m_useAGC || force)
 | 
			
		||||
	{
 | 
			
		||||
		emit setWorkerGain(settings.m_gain, settings.m_useAGC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    if (m_settings.m_centerFrequency != settings.m_centerFrequency || force)
 | 
			
		||||
    {
 | 
			
		||||
        reverseAPIKeys.append("centerFrequency");
 | 
			
		||||
 | 
			
		||||
        emit setWorkerCenterFrequency(settings.m_centerFrequency);
 | 
			
		||||
 | 
			
		||||
		DSPSignalNotification *notif = new DSPSignalNotification(
 | 
			
		||||
			getSampleRate(), settings.m_centerFrequency);
 | 
			
		||||
		m_fileSink->handleMessage(*notif); // forward to file sink
 | 
			
		||||
		m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    if (settings.m_useReverseAPI)
 | 
			
		||||
    {
 | 
			
		||||
        qDebug("KiwiSDRInput::applySettings: call webapiReverseSendSettings");
 | 
			
		||||
        bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
 | 
			
		||||
                (m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
 | 
			
		||||
                (m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
 | 
			
		||||
                (m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex);
 | 
			
		||||
        webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_settings = settings;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int KiwiSDRInput::webapiRunGet(
 | 
			
		||||
        SWGSDRangel::SWGDeviceState& response,
 | 
			
		||||
        QString& errorMessage)
 | 
			
		||||
{
 | 
			
		||||
    return 404;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int KiwiSDRInput::webapiRun(
 | 
			
		||||
        bool run,
 | 
			
		||||
        SWGSDRangel::SWGDeviceState& response,
 | 
			
		||||
        QString& errorMessage)
 | 
			
		||||
{
 | 
			
		||||
	return 404;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int KiwiSDRInput::webapiSettingsGet(
 | 
			
		||||
                SWGSDRangel::SWGDeviceSettings& response,
 | 
			
		||||
                QString& errorMessage)
 | 
			
		||||
{
 | 
			
		||||
    return 404;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int KiwiSDRInput::webapiSettingsPutPatch(
 | 
			
		||||
                bool force,
 | 
			
		||||
                const QStringList& deviceSettingsKeys,
 | 
			
		||||
                SWGSDRangel::SWGDeviceSettings& response, // query + response
 | 
			
		||||
                QString& errorMessage)
 | 
			
		||||
{
 | 
			
		||||
    return 404;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const KiwiSDRSettings& settings)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const KiwiSDRSettings& settings, bool force)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::webapiReverseSendStartStop(bool start)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRInput::networkManagerFinished(QNetworkReply *reply)
 | 
			
		||||
{
 | 
			
		||||
    QNetworkReply::NetworkError replyError = reply->error();
 | 
			
		||||
 | 
			
		||||
    if (replyError)
 | 
			
		||||
    {
 | 
			
		||||
        qWarning() << "KiwiSDRInput::networkManagerFinished:"
 | 
			
		||||
                << " error(" << (int) replyError
 | 
			
		||||
                << "): " << replyError
 | 
			
		||||
                << ": " << reply->errorString();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QString answer = reply->readAll();
 | 
			
		||||
    answer.chop(1); // remove last \n
 | 
			
		||||
    qDebug("KiwiSDRInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										189
									
								
								plugins/samplesource/kiwisdr/kiwisdrinput.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								plugins/samplesource/kiwisdr/kiwisdrinput.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,189 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef _KIWISDR_KIWISDRINPUT_H_
 | 
			
		||||
#define _KIWISDR_KIWISDRINPUT_H_
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QNetworkRequest>
 | 
			
		||||
 | 
			
		||||
#include <dsp/devicesamplesource.h>
 | 
			
		||||
#include "kiwisdrsettings.h"
 | 
			
		||||
 | 
			
		||||
class DeviceAPI;
 | 
			
		||||
class KiwiSDRWorker;
 | 
			
		||||
class FileRecord;
 | 
			
		||||
class QNetworkAccessManager;
 | 
			
		||||
class QNetworkReply;
 | 
			
		||||
 | 
			
		||||
class KiwiSDRInput : public DeviceSampleSource {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
	class MsgConfigureKiwiSDR : public Message {
 | 
			
		||||
		MESSAGE_CLASS_DECLARATION
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const KiwiSDRSettings& getSettings() const { return m_settings; }
 | 
			
		||||
		bool getForce() const { return m_force; }
 | 
			
		||||
 | 
			
		||||
		static MsgConfigureKiwiSDR* create(const KiwiSDRSettings& settings, bool force)
 | 
			
		||||
		{
 | 
			
		||||
			return new MsgConfigureKiwiSDR(settings, force);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		KiwiSDRSettings m_settings;
 | 
			
		||||
		bool m_force;
 | 
			
		||||
 | 
			
		||||
		MsgConfigureKiwiSDR(const KiwiSDRSettings& settings, bool force) :
 | 
			
		||||
			Message(),
 | 
			
		||||
			m_settings(settings),
 | 
			
		||||
			m_force(force)
 | 
			
		||||
		{ }
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
    class MsgFileRecord : public Message {
 | 
			
		||||
        MESSAGE_CLASS_DECLARATION
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        bool getStartStop() const { return m_startStop; }
 | 
			
		||||
 | 
			
		||||
        static MsgFileRecord* create(bool startStop) {
 | 
			
		||||
            return new MsgFileRecord(startStop);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
        bool m_startStop;
 | 
			
		||||
 | 
			
		||||
        MsgFileRecord(bool startStop) :
 | 
			
		||||
            Message(),
 | 
			
		||||
            m_startStop(startStop)
 | 
			
		||||
        { }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class MsgStartStop : public Message {
 | 
			
		||||
        MESSAGE_CLASS_DECLARATION
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        bool getStartStop() const { return m_startStop; }
 | 
			
		||||
 | 
			
		||||
        static MsgStartStop* create(bool startStop) {
 | 
			
		||||
            return new MsgStartStop(startStop);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
        bool m_startStop;
 | 
			
		||||
 | 
			
		||||
        MsgStartStop(bool startStop) :
 | 
			
		||||
            Message(),
 | 
			
		||||
            m_startStop(startStop)
 | 
			
		||||
        { }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	class MsgSetStatus : public Message {
 | 
			
		||||
		MESSAGE_CLASS_DECLARATION
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		int getStatus() const { return m_status; }
 | 
			
		||||
 | 
			
		||||
		static MsgSetStatus* create(int status) {
 | 
			
		||||
			return new MsgSetStatus(status);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		int m_status;
 | 
			
		||||
 | 
			
		||||
		MsgSetStatus(int status) :
 | 
			
		||||
			Message(),
 | 
			
		||||
			m_status(status)
 | 
			
		||||
		{ }
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	KiwiSDRInput(DeviceAPI *deviceAPI);
 | 
			
		||||
	virtual ~KiwiSDRInput();
 | 
			
		||||
	virtual void destroy();
 | 
			
		||||
 | 
			
		||||
	virtual void init();
 | 
			
		||||
	virtual bool start();
 | 
			
		||||
	virtual void stop();
 | 
			
		||||
 | 
			
		||||
    virtual QByteArray serialize() const;
 | 
			
		||||
    virtual bool deserialize(const QByteArray& data);
 | 
			
		||||
 | 
			
		||||
    virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
 | 
			
		||||
	virtual const QString& getDeviceDescription() const;
 | 
			
		||||
	virtual int getSampleRate() const;
 | 
			
		||||
    virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
 | 
			
		||||
	virtual quint64 getCenterFrequency() const;
 | 
			
		||||
    virtual void setCenterFrequency(qint64 centerFrequency);
 | 
			
		||||
 | 
			
		||||
	virtual bool handleMessage(const Message& message);
 | 
			
		||||
 | 
			
		||||
    virtual int webapiSettingsGet(
 | 
			
		||||
                SWGSDRangel::SWGDeviceSettings& response,
 | 
			
		||||
                QString& errorMessage);
 | 
			
		||||
 | 
			
		||||
    virtual int webapiSettingsPutPatch(
 | 
			
		||||
                bool force,
 | 
			
		||||
                const QStringList& deviceSettingsKeys,
 | 
			
		||||
                SWGSDRangel::SWGDeviceSettings& response, // query + response
 | 
			
		||||
                QString& errorMessage);
 | 
			
		||||
 | 
			
		||||
    virtual int webapiRunGet(
 | 
			
		||||
            SWGSDRangel::SWGDeviceState& response,
 | 
			
		||||
            QString& errorMessage);
 | 
			
		||||
 | 
			
		||||
    virtual int webapiRun(
 | 
			
		||||
            bool run,
 | 
			
		||||
            SWGSDRangel::SWGDeviceState& response,
 | 
			
		||||
            QString& errorMessage);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	DeviceAPI *m_deviceAPI;
 | 
			
		||||
    FileRecord *m_fileSink; //!< File sink to record device I/Q output
 | 
			
		||||
	QMutex m_mutex;
 | 
			
		||||
	KiwiSDRSettings m_settings;
 | 
			
		||||
	KiwiSDRWorker* m_kiwiSDRWorker;
 | 
			
		||||
	QThread m_kiwiSDRWorkerThread;
 | 
			
		||||
	QString m_deviceDescription;
 | 
			
		||||
	bool m_running;
 | 
			
		||||
    const QTimer& m_masterTimer;
 | 
			
		||||
    QNetworkAccessManager *m_networkManager;
 | 
			
		||||
    QNetworkRequest m_networkRequest;
 | 
			
		||||
 | 
			
		||||
	bool applySettings(const KiwiSDRSettings& settings, bool force);
 | 
			
		||||
    void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const KiwiSDRSettings& settings);
 | 
			
		||||
    void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const KiwiSDRSettings& settings, bool force);
 | 
			
		||||
    void webapiReverseSendStartStop(bool start);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void startWorker();
 | 
			
		||||
	void stopWorker();
 | 
			
		||||
	void setWorkerCenterFrequency(quint64 centerFrequency);
 | 
			
		||||
	void setWorkerServerAddress(QString serverAddress);
 | 
			
		||||
	void setWorkerGain(quint32 gain, bool useAGC);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void setWorkerStatus(int status);
 | 
			
		||||
    void networkManagerFinished(QNetworkReply *reply);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _KIWISDR_KIWISDRINPUT_H_
 | 
			
		||||
							
								
								
									
										111
									
								
								plugins/samplesource/kiwisdr/kiwisdrplugin.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								plugins/samplesource/kiwisdr/kiwisdrplugin.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,111 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <QtPlugin>
 | 
			
		||||
 | 
			
		||||
#include "plugin/pluginapi.h"
 | 
			
		||||
#include "util/simpleserializer.h"
 | 
			
		||||
 | 
			
		||||
#ifdef SERVER_MODE
 | 
			
		||||
#include "kiwisdrinput.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "kiwisdrgui.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "kiwisdrplugin.h"
 | 
			
		||||
 | 
			
		||||
const PluginDescriptor KiwiSDRPlugin::m_pluginDescriptor = {
 | 
			
		||||
	QString("KiwiSDR input"),
 | 
			
		||||
	QString("0.0.1"),
 | 
			
		||||
	QString("(c) Vort (c) Edouard Griffiths, F4EXB"),
 | 
			
		||||
	QString("https://github.com/f4exb/sdrangel"),
 | 
			
		||||
	true,
 | 
			
		||||
	QString("https://github.com/f4exb/sdrangel")
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const QString KiwiSDRPlugin::m_hardwareID = "KiwiSDR";
 | 
			
		||||
const QString KiwiSDRPlugin::m_deviceTypeID = KIWISDR_DEVICE_TYPE_ID;
 | 
			
		||||
 | 
			
		||||
KiwiSDRPlugin::KiwiSDRPlugin(QObject* parent) :
 | 
			
		||||
	QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PluginDescriptor& KiwiSDRPlugin::getPluginDescriptor() const
 | 
			
		||||
{
 | 
			
		||||
	return m_pluginDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRPlugin::initPlugin(PluginAPI* pluginAPI)
 | 
			
		||||
{
 | 
			
		||||
	pluginAPI->registerSampleSource(m_deviceTypeID, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PluginInterface::SamplingDevices KiwiSDRPlugin::enumSampleSources()
 | 
			
		||||
{
 | 
			
		||||
	SamplingDevices result;
 | 
			
		||||
 | 
			
		||||
    result.append(SamplingDevice(
 | 
			
		||||
            "KiwiSDR",
 | 
			
		||||
            m_hardwareID,
 | 
			
		||||
            m_deviceTypeID,
 | 
			
		||||
            QString::null,
 | 
			
		||||
            0,
 | 
			
		||||
            PluginInterface::SamplingDevice::BuiltInDevice,
 | 
			
		||||
            PluginInterface::SamplingDevice::StreamSingleRx,
 | 
			
		||||
            1,
 | 
			
		||||
            0));
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef SERVER_MODE
 | 
			
		||||
PluginInstanceGUI* KiwiSDRPlugin::createSampleSourcePluginInstanceGUI(
 | 
			
		||||
        const QString& sourceId,
 | 
			
		||||
        QWidget **widget,
 | 
			
		||||
        DeviceUISet *deviceUISet)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
PluginInstanceGUI* KiwiSDRPlugin::createSampleSourcePluginInstanceGUI(
 | 
			
		||||
        const QString& sourceId,
 | 
			
		||||
        QWidget **widget,
 | 
			
		||||
        DeviceUISet *deviceUISet)
 | 
			
		||||
{
 | 
			
		||||
	if(sourceId == m_deviceTypeID) {
 | 
			
		||||
		KiwiSDRGui* gui = new KiwiSDRGui(deviceUISet);
 | 
			
		||||
		*widget = gui;
 | 
			
		||||
		return gui;
 | 
			
		||||
	} else {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
DeviceSampleSource *KiwiSDRPlugin::createSampleSourcePluginInstance(const QString& sourceId, DeviceAPI *deviceAPI)
 | 
			
		||||
{
 | 
			
		||||
    if (sourceId == m_deviceTypeID)
 | 
			
		||||
    {
 | 
			
		||||
		KiwiSDRInput* input = new KiwiSDRInput(deviceAPI);
 | 
			
		||||
        return input;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										53
									
								
								plugins/samplesource/kiwisdr/kiwisdrplugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								plugins/samplesource/kiwisdr/kiwisdrplugin.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef _KIWISDR_KIWISDRPLUGIN_H
 | 
			
		||||
#define _KIWISDR_KIWISDRPLUGIN_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include "plugin/plugininterface.h"
 | 
			
		||||
 | 
			
		||||
class PluginAPI;
 | 
			
		||||
 | 
			
		||||
#define KIWISDR_DEVICE_TYPE_ID "sdrangel.samplesource.kiwisdrsource"
 | 
			
		||||
 | 
			
		||||
class KiwiSDRPlugin : public QObject, public PluginInterface {
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
	Q_INTERFACES(PluginInterface)
 | 
			
		||||
	Q_PLUGIN_METADATA(IID KIWISDR_DEVICE_TYPE_ID)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	explicit KiwiSDRPlugin(QObject* parent = NULL);
 | 
			
		||||
 | 
			
		||||
	const PluginDescriptor& getPluginDescriptor() const;
 | 
			
		||||
	void initPlugin(PluginAPI* pluginAPI);
 | 
			
		||||
 | 
			
		||||
	virtual SamplingDevices enumSampleSources();
 | 
			
		||||
	virtual PluginInstanceGUI* createSampleSourcePluginInstanceGUI(
 | 
			
		||||
	        const QString& sourceId,
 | 
			
		||||
	        QWidget **widget,
 | 
			
		||||
	        DeviceUISet *deviceUISet);
 | 
			
		||||
	virtual DeviceSampleSource* createSampleSourcePluginInstance(const QString& sourceId, DeviceAPI *deviceAPI);
 | 
			
		||||
 | 
			
		||||
	static const QString m_hardwareID;
 | 
			
		||||
    static const QString m_deviceTypeID;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	static const PluginDescriptor m_pluginDescriptor;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _KIWISDR_KIWISDRPLUGIN_H
 | 
			
		||||
							
								
								
									
										103
									
								
								plugins/samplesource/kiwisdr/kiwisdrsettings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								plugins/samplesource/kiwisdr/kiwisdrsettings.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,103 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include "util/simpleserializer.h"
 | 
			
		||||
#include "kiwisdrsettings.h"
 | 
			
		||||
 | 
			
		||||
KiwiSDRSettings::KiwiSDRSettings()
 | 
			
		||||
{
 | 
			
		||||
    resetToDefaults();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRSettings::resetToDefaults()
 | 
			
		||||
{
 | 
			
		||||
    m_centerFrequency = 1450000;
 | 
			
		||||
 | 
			
		||||
	m_gain = 20;
 | 
			
		||||
	m_useAGC = true;
 | 
			
		||||
 | 
			
		||||
	m_serverAddress = "127.0.0.1:8073";
 | 
			
		||||
 | 
			
		||||
    m_useReverseAPI = false;
 | 
			
		||||
    m_reverseAPIAddress = "127.0.0.1";
 | 
			
		||||
    m_reverseAPIPort = 8888;
 | 
			
		||||
    m_reverseAPIDeviceIndex = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray KiwiSDRSettings::serialize() const
 | 
			
		||||
{
 | 
			
		||||
    SimpleSerializer s(2);
 | 
			
		||||
 | 
			
		||||
	s.writeString(2, m_serverAddress);
 | 
			
		||||
	s.writeU32(3, m_gain);
 | 
			
		||||
	s.writeBool(4, m_useAGC);
 | 
			
		||||
 | 
			
		||||
    s.writeBool(100, m_useReverseAPI);
 | 
			
		||||
    s.writeString(101, m_reverseAPIAddress);
 | 
			
		||||
    s.writeU32(102, m_reverseAPIPort);
 | 
			
		||||
    s.writeU32(103, m_reverseAPIDeviceIndex);
 | 
			
		||||
 | 
			
		||||
	return s.final();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KiwiSDRSettings::deserialize(const QByteArray& data)
 | 
			
		||||
{
 | 
			
		||||
    SimpleDeserializer d(data);
 | 
			
		||||
 | 
			
		||||
    if (!d.isValid())
 | 
			
		||||
    {
 | 
			
		||||
        resetToDefaults();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (d.getVersion() == 2)
 | 
			
		||||
    {
 | 
			
		||||
		uint32_t utmp;
 | 
			
		||||
 | 
			
		||||
		d.readString(2, &m_serverAddress, "127.0.0.1:8073");
 | 
			
		||||
		d.readU32(3, &m_gain, 20);
 | 
			
		||||
		d.readBool(4, &m_useAGC, true);
 | 
			
		||||
 | 
			
		||||
		d.readBool(100, &m_useReverseAPI, false);
 | 
			
		||||
		d.readString(101, &m_reverseAPIAddress, "127.0.0.1");
 | 
			
		||||
		d.readU32(102, &utmp, 0);
 | 
			
		||||
 | 
			
		||||
		if ((utmp > 1023) && (utmp < 65535)) {
 | 
			
		||||
			m_reverseAPIPort = utmp;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			m_reverseAPIPort = 8888;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		d.readU32(103, &utmp, 0);
 | 
			
		||||
		m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        resetToDefaults();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								plugins/samplesource/kiwisdr/kiwisdrsettings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								plugins/samplesource/kiwisdr/kiwisdrsettings.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB                                   //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef _KIWISDR_KIWISDRSETTINGS_H_
 | 
			
		||||
#define _KIWISDR_KIWISDRSETTINGS_H_
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
 | 
			
		||||
struct KiwiSDRSettings {
 | 
			
		||||
	uint32_t m_gain;
 | 
			
		||||
	bool m_useAGC;
 | 
			
		||||
 | 
			
		||||
    quint64 m_centerFrequency;
 | 
			
		||||
	QString m_serverAddress;
 | 
			
		||||
 | 
			
		||||
	bool m_useReverseAPI;
 | 
			
		||||
    QString m_reverseAPIAddress;
 | 
			
		||||
    uint16_t m_reverseAPIPort;
 | 
			
		||||
    uint16_t m_reverseAPIDeviceIndex;
 | 
			
		||||
 | 
			
		||||
	KiwiSDRSettings();
 | 
			
		||||
	void resetToDefaults();
 | 
			
		||||
	QByteArray serialize() const;
 | 
			
		||||
	bool deserialize(const QByteArray& data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* _KIWISDR_KIWISDRSETTINGS_H_ */
 | 
			
		||||
							
								
								
									
										147
									
								
								plugins/samplesource/kiwisdr/kiwisdrworker.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								plugins/samplesource/kiwisdr/kiwisdrworker.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include <boost/endian/conversion.hpp>
 | 
			
		||||
#include "kiwisdrworker.h"
 | 
			
		||||
 | 
			
		||||
KiwiSDRWorker::KiwiSDRWorker(SampleSinkFifo* sampleFifo)
 | 
			
		||||
	: QObject(),
 | 
			
		||||
	m_timer(this),
 | 
			
		||||
	m_sampleFifo(sampleFifo),
 | 
			
		||||
	m_samplesBuf(),
 | 
			
		||||
	m_centerFrequency(1450000),
 | 
			
		||||
	m_gain(20),
 | 
			
		||||
	m_useAGC(true)
 | 
			
		||||
{
 | 
			
		||||
	connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
 | 
			
		||||
 | 
			
		||||
	m_webSocket.setParent(this);
 | 
			
		||||
	connect(&m_webSocket, &QWebSocket::connected,
 | 
			
		||||
		this, &KiwiSDRWorker::onConnected);
 | 
			
		||||
	connect(&m_webSocket, &QWebSocket::binaryMessageReceived,
 | 
			
		||||
		this, &KiwiSDRWorker::onBinaryMessageReceived);
 | 
			
		||||
	connect(&m_webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
 | 
			
		||||
		this, &KiwiSDRWorker::onSocketError);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::onConnected()
 | 
			
		||||
{
 | 
			
		||||
	m_webSocket.sendTextMessage("SET auth t=kiwi p=#");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::onSocketError(QAbstractSocket::SocketError error)
 | 
			
		||||
{
 | 
			
		||||
	emit updateStatus(3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::sendCenterFrequency()
 | 
			
		||||
{
 | 
			
		||||
	if (!m_webSocket.isValid())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	QString freq = QString::number(m_centerFrequency / 1000.0, 'f', 3);
 | 
			
		||||
	QString msg = "SET mod=iq low_cut=-5980 high_cut=5980 freq=" + freq;
 | 
			
		||||
	m_webSocket.sendTextMessage(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::sendGain()
 | 
			
		||||
{
 | 
			
		||||
	if (!m_webSocket.isValid())
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	QString msg("SET agc=");
 | 
			
		||||
	msg.append(m_useAGC ? "1" : "0");
 | 
			
		||||
	msg.append(" hang=0 thresh=-130 slope=6 decay=1000 manGain=");
 | 
			
		||||
	msg.append(QString::number(m_gain));
 | 
			
		||||
	m_webSocket.sendTextMessage(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::onBinaryMessageReceived(const QByteArray &message)
 | 
			
		||||
{
 | 
			
		||||
	if (message[0] == 'M' && message[1] == 'S' && message[2] == 'G')
 | 
			
		||||
	{
 | 
			
		||||
		QStringList al = QString::fromUtf8(message).split(' ');
 | 
			
		||||
		if (al[1] == "audio_init=0" &&
 | 
			
		||||
			al[2] == "audio_rate=12000")
 | 
			
		||||
		{
 | 
			
		||||
			m_webSocket.sendTextMessage("SET AR OK in=12000 out=48000");
 | 
			
		||||
			m_webSocket.sendTextMessage("SERVER DE CLIENT KiwiAngel SND");
 | 
			
		||||
			sendGain();
 | 
			
		||||
			sendCenterFrequency();
 | 
			
		||||
			m_timer.start(5000);
 | 
			
		||||
			emit updateStatus(2);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (message[0] == 'S' && message[1] == 'N' && message[2] == 'D')
 | 
			
		||||
	{
 | 
			
		||||
		int dataOffset = 20;
 | 
			
		||||
		int sampleCount = 512;
 | 
			
		||||
		const int16_t* messageSamples = (const int16_t*)(message.constData() + dataOffset);
 | 
			
		||||
 | 
			
		||||
		m_samplesBuf.clear();
 | 
			
		||||
		for (int i = 0; i < sampleCount; i++)
 | 
			
		||||
		{
 | 
			
		||||
			m_samplesBuf.push_back(Sample(
 | 
			
		||||
				boost::endian::endian_reverse(messageSamples[i * 2]) << (SDR_RX_SAMP_SZ - 16),
 | 
			
		||||
				boost::endian::endian_reverse(messageSamples[i * 2 + 1]) << (SDR_RX_SAMP_SZ - 16)
 | 
			
		||||
			));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_sampleFifo->write(m_samplesBuf.begin(), m_samplesBuf.end());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::onCenterFrequencyChanged(quint64 centerFrequency)
 | 
			
		||||
{
 | 
			
		||||
	if (m_centerFrequency == centerFrequency)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	m_centerFrequency = centerFrequency;
 | 
			
		||||
	sendCenterFrequency();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::onGainChanged(quint32 gain, bool useAGC)
 | 
			
		||||
{
 | 
			
		||||
	if (m_gain == gain && m_useAGC == useAGC)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	m_gain = gain;
 | 
			
		||||
	m_useAGC = useAGC;
 | 
			
		||||
 | 
			
		||||
	sendGain();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::onServerAddressChanged(QString serverAddress)
 | 
			
		||||
{
 | 
			
		||||
	if (m_serverAddress == serverAddress)
 | 
			
		||||
		return;
 | 
			
		||||
	m_serverAddress = serverAddress;
 | 
			
		||||
 | 
			
		||||
	emit updateStatus(1);
 | 
			
		||||
 | 
			
		||||
	QString url("ws://");
 | 
			
		||||
	url.append(m_serverAddress);
 | 
			
		||||
	url.append("/kiwi/");
 | 
			
		||||
	url.append(QString::number(QDateTime::currentMSecsSinceEpoch()));
 | 
			
		||||
	url.append("/SND");
 | 
			
		||||
	m_webSocket.open(QUrl(url));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KiwiSDRWorker::tick()
 | 
			
		||||
{
 | 
			
		||||
	m_webSocket.sendTextMessage("SET keepalive");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								plugins/samplesource/kiwisdr/kiwisdrworker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								plugins/samplesource/kiwisdr/kiwisdrworker.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2019 Vort                                                       //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef _KIWISDR_KIWISDRWORKER_H_
 | 
			
		||||
#define _KIWISDR_KIWISDRWORKER_H_
 | 
			
		||||
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QtWebSockets/QtWebSockets>
 | 
			
		||||
 | 
			
		||||
#include "dsp/samplesinkfifo.h"
 | 
			
		||||
 | 
			
		||||
class KiwiSDRWorker : public QObject {
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	KiwiSDRWorker(SampleSinkFifo* sampleFifo);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QTimer m_timer;
 | 
			
		||||
	QWebSocket m_webSocket;
 | 
			
		||||
 | 
			
		||||
	SampleVector m_samplesBuf;
 | 
			
		||||
	SampleSinkFifo* m_sampleFifo;
 | 
			
		||||
 | 
			
		||||
	QString m_serverAddress;
 | 
			
		||||
	uint64_t m_centerFrequency;
 | 
			
		||||
 | 
			
		||||
	uint32_t m_gain;
 | 
			
		||||
	bool m_useAGC;
 | 
			
		||||
 | 
			
		||||
	void sendCenterFrequency();
 | 
			
		||||
	void sendGain();
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void updateStatus(int status);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
	void onCenterFrequencyChanged(quint64 centerFrequency);
 | 
			
		||||
	void onServerAddressChanged(QString serverAddress);
 | 
			
		||||
	void onGainChanged(quint32 gain, bool useAGC);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void onConnected();
 | 
			
		||||
	void onBinaryMessageReceived(const QByteArray &message);
 | 
			
		||||
	void onSocketError(QAbstractSocket::SocketError error);
 | 
			
		||||
 | 
			
		||||
    void tick();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _KIWISDR_KIWISDRWORKER_H_
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user