From 53925bd4fddf613badf7391fd6d08f0049f797df Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 14 Dec 2017 00:19:59 +0100 Subject: [PATCH] Web API: fixed segfault when mixing start/stop between GUI and API. Applied to BladeRF input, SDRdaemon input and SDRPlay --- .../bladerfinput/bladerfinput.cpp | 40 ++++++++++++++----- .../samplesource/bladerfinput/bladerfinput.h | 21 +++++++++- .../bladerfinput/bladerfinputgui.cpp | 37 +++++++++++------ .../sdrdaemonsource/sdrdaemonsourcegui.cpp | 23 ++++++----- .../sdrdaemonsource/sdrdaemonsourceinput.cpp | 40 ++++++++++++++----- .../sdrdaemonsource/sdrdaemonsourceinput.h | 19 +++++++++ plugins/samplesource/sdrplay/sdrplaygui.cpp | 24 ++++++----- plugins/samplesource/sdrplay/sdrplaygui.h | 2 + plugins/samplesource/sdrplay/sdrplayinput.cpp | 40 ++++++++++++++----- plugins/samplesource/sdrplay/sdrplayinput.h | 19 +++++++++ 10 files changed, 199 insertions(+), 66 deletions(-) diff --git a/plugins/samplesource/bladerfinput/bladerfinput.cpp b/plugins/samplesource/bladerfinput/bladerfinput.cpp index 06cffba9f..f8e82f5a8 100644 --- a/plugins/samplesource/bladerfinput/bladerfinput.cpp +++ b/plugins/samplesource/bladerfinput/bladerfinput.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "SWGDeviceSettings.h" @@ -34,6 +35,7 @@ #include "bladerfinputthread.h" MESSAGE_CLASS_DEFINITION(BladerfInput::MsgConfigureBladerf, Message) +MESSAGE_CLASS_DEFINITION(BladerfInput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(BladerfInput::MsgFileRecord, Message) BladerfInput::BladerfInput(DeviceSourceAPI *deviceAPI) : @@ -244,6 +246,27 @@ bool BladerfInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "BladerfInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else { return false; @@ -558,19 +581,16 @@ int BladerfInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/bladerfinput/bladerfinput.h b/plugins/samplesource/bladerfinput/bladerfinput.h index 4d6321db6..5b464dcc2 100644 --- a/plugins/samplesource/bladerfinput/bladerfinput.h +++ b/plugins/samplesource/bladerfinput/bladerfinput.h @@ -74,7 +74,26 @@ public: { } }; - BladerfInput(DeviceSourceAPI *deviceAPI); + 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) + { } + }; + + BladerfInput(DeviceSourceAPI *deviceAPI); virtual ~BladerfInput(); virtual void destroy(); diff --git a/plugins/samplesource/bladerfinput/bladerfinputgui.cpp b/plugins/samplesource/bladerfinput/bladerfinputgui.cpp index d7236cb36..1f2cc5fe5 100644 --- a/plugins/samplesource/bladerfinput/bladerfinputgui.cpp +++ b/plugins/samplesource/bladerfinput/bladerfinputgui.cpp @@ -124,9 +124,21 @@ bool BladerfInputGui::deserialize(const QByteArray& data) } } -bool BladerfInputGui::handleMessage(const Message& message __attribute__((unused))) +bool BladerfInputGui::handleMessage(const Message& message) { - return false; + if (BladerfInput::MsgStartStop::match(message)) + { + BladerfInput::MsgStartStop& notif = (BladerfInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } + else + { + return false; + } } void BladerfInputGui::handleInputMessages() @@ -147,6 +159,13 @@ void BladerfInputGui::handleInputMessages() delete message; } + else + { + if (handleMessage(*message)) + { + delete message; + } + } } } @@ -339,18 +358,10 @@ void BladerfInputGui::on_xb200_currentIndexChanged(int index) void BladerfInputGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + BladerfInput::MsgStartStop *message = BladerfInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp index fc5ed4014..00fb3b2e9 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp @@ -247,6 +247,15 @@ bool SDRdaemonSourceGui::handleMessage(const Message& message) updateWithStreamTime(); return true; } + else if (SDRdaemonSourceInput::MsgStartStop::match(message)) + { + SDRdaemonSourceInput::MsgStartStop& notif = (SDRdaemonSourceInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } else { return false; @@ -591,18 +600,10 @@ void SDRdaemonSourceGui::on_nbFECBlocks_valueChanged(int value) void SDRdaemonSourceGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + SDRdaemonSourceInput::MsgStartStop *message = SDRdaemonSourceInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp index bfd2c03ef..86bfb4c5b 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "SWGDeviceSettings.h" @@ -40,6 +41,7 @@ MESSAGE_CLASS_DEFINITION(SDRdaemonSourceInput::MsgReportSDRdaemonAcquisition, Me MESSAGE_CLASS_DEFINITION(SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonSourceInput::MsgFileRecord, Message) +MESSAGE_CLASS_DEFINITION(SDRdaemonSourceInput::MsgStartStop, Message) SDRdaemonSourceInput::SDRdaemonSourceInput(DeviceSourceAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -138,6 +140,27 @@ bool SDRdaemonSourceInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "SDRdaemonSourceInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else if (MsgConfigureSDRdaemonSource::match(message)) { qDebug() << "SDRdaemonSourceInput::handleMessage:" << message.getIdentifier(); @@ -222,19 +245,16 @@ int SDRdaemonSourceInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h index 3307ee795..cc5f1f02e 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h @@ -303,6 +303,25 @@ public: { } }; + 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) + { } + }; + SDRdaemonSourceInput(DeviceSourceAPI *deviceAPI); virtual ~SDRdaemonSourceInput(); virtual void destroy(); diff --git a/plugins/samplesource/sdrplay/sdrplaygui.cpp b/plugins/samplesource/sdrplay/sdrplaygui.cpp index 790f9a75d..b8ecf7180 100644 --- a/plugins/samplesource/sdrplay/sdrplaygui.cpp +++ b/plugins/samplesource/sdrplay/sdrplaygui.cpp @@ -33,6 +33,7 @@ SDRPlayGui::SDRPlayGui(DeviceUISet *deviceUISet, QWidget* parent) : QWidget(parent), ui(new Ui::SDRPlayGui), m_deviceUISet(deviceUISet), + m_doApplySettings(true), m_forceSettings(true) { m_sampleSource = (SDRPlayInput*) m_deviceUISet->m_deviceSourceAPI->getSampleSource(); @@ -163,6 +164,15 @@ bool SDRPlayGui::handleMessage(const Message& message) return true; } + else if (SDRPlayInput::MsgStartStop::match(message)) + { + SDRPlayInput::MsgStartStop& notif = (SDRPlayInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } else { return false; @@ -433,18 +443,10 @@ void SDRPlayGui::on_gainBaseband_valueChanged(int value) void SDRPlayGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + SDRPlayInput::MsgStartStop *message = SDRPlayInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/sdrplay/sdrplaygui.h b/plugins/samplesource/sdrplay/sdrplaygui.h index ea0f08b70..cab175969 100644 --- a/plugins/samplesource/sdrplay/sdrplaygui.h +++ b/plugins/samplesource/sdrplay/sdrplaygui.h @@ -57,6 +57,7 @@ private: Ui::SDRPlayGui* ui; DeviceUISet* m_deviceUISet; + bool m_doApplySettings; bool m_forceSettings; SDRPlaySettings m_settings; QTimer m_updateTimer; @@ -67,6 +68,7 @@ private: int m_lastEngineState; MessageQueue m_inputMessageQueue; + void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); void sendSettings(); void updateSampleRateAndFrequency(); diff --git a/plugins/samplesource/sdrplay/sdrplayinput.cpp b/plugins/samplesource/sdrplay/sdrplayinput.cpp index 6376c2a48..32a4af40a 100644 --- a/plugins/samplesource/sdrplay/sdrplayinput.cpp +++ b/plugins/samplesource/sdrplay/sdrplayinput.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "SWGDeviceSettings.h" @@ -35,6 +36,7 @@ MESSAGE_CLASS_DEFINITION(SDRPlayInput::MsgConfigureSDRPlay, Message) MESSAGE_CLASS_DEFINITION(SDRPlayInput::MsgReportSDRPlayGains, Message) MESSAGE_CLASS_DEFINITION(SDRPlayInput::MsgFileRecord, Message) +MESSAGE_CLASS_DEFINITION(SDRPlayInput::MsgStartStop, Message) SDRPlayInput::SDRPlayInput(DeviceSourceAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -256,6 +258,27 @@ bool SDRPlayInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "SDRPlayInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else { return false; @@ -582,19 +605,16 @@ int SDRPlayInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/sdrplay/sdrplayinput.h b/plugins/samplesource/sdrplay/sdrplayinput.h index 64fec2227..eb90331f7 100644 --- a/plugins/samplesource/sdrplay/sdrplayinput.h +++ b/plugins/samplesource/sdrplay/sdrplayinput.h @@ -101,6 +101,25 @@ public: { } }; + 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) + { } + }; + SDRPlayInput(DeviceSourceAPI *deviceAPI); virtual ~SDRPlayInput(); virtual void destroy();