mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04:00 
			
		
		
		
	RemoteOutput: remove from GUI all API interactions with the remote
This commit is contained in:
		
							parent
							
								
									96411edd3c
								
							
						
					
					
						commit
						a5948c8b24
					
				| @ -41,6 +41,10 @@ MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutput, Message) | |||||||
| MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputWork, Message) | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputWork, Message) | ||||||
| MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgStartStop, Message) | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgStartStop, Message) | ||||||
| MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputChunkCorrection, Message) | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputChunkCorrection, Message) | ||||||
|  | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputSampleRate, Message) | ||||||
|  | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgReportRemoteData, Message) | ||||||
|  | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgReportRemoteFixedData, Message) | ||||||
|  | MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgRequestFixedData, Message) | ||||||
| 
 | 
 | ||||||
| const uint32_t RemoteOutput::NbSamplesForRateCorrection = 5000000; | const uint32_t RemoteOutput::NbSamplesForRateCorrection = 5000000; | ||||||
| 
 | 
 | ||||||
| @ -53,7 +57,8 @@ RemoteOutput::RemoteOutput(DeviceAPI *deviceAPI) : | |||||||
|     m_startingTimeStamp(0), |     m_startingTimeStamp(0), | ||||||
| 	m_masterTimer(deviceAPI->getMasterTimer()), | 	m_masterTimer(deviceAPI->getMasterTimer()), | ||||||
| 	m_tickCount(0), | 	m_tickCount(0), | ||||||
|     m_tickMultiplier(20), |     m_greaterTickCount(0), | ||||||
|  |     m_tickMultiplier(1), | ||||||
| 	m_lastRemoteSampleCount(0), | 	m_lastRemoteSampleCount(0), | ||||||
| 	m_lastSampleCount(0), | 	m_lastSampleCount(0), | ||||||
| 	m_lastRemoteTimestampRateCorrection(0), | 	m_lastRemoteTimestampRateCorrection(0), | ||||||
| @ -243,6 +248,19 @@ bool RemoteOutput::handleMessage(const Message& message) | |||||||
| 
 | 
 | ||||||
| 	    return true; | 	    return true; | ||||||
| 	} | 	} | ||||||
|  |     else if (MsgRequestFixedData::match(message)) | ||||||
|  |     { | ||||||
|  |         QString reportURL; | ||||||
|  | 
 | ||||||
|  |         reportURL = QString("http://%1:%2/sdrangel") | ||||||
|  |             .arg(m_settings.m_apiAddress) | ||||||
|  |             .arg(m_settings.m_apiPort); | ||||||
|  | 
 | ||||||
|  |         m_networkRequest.setUrl(QUrl(reportURL)); | ||||||
|  |         m_networkManager->get(m_networkRequest); | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		return false; | 		return false; | ||||||
| @ -284,8 +302,8 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool forc | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         m_tickMultiplier = (21*NbSamplesForRateCorrection) / (2*settings.m_sampleRate); // two times per sample filling period plus small extension
 |         m_tickMultiplier = (21*NbSamplesForRateCorrection) / (2*settings.m_sampleRate); // two times per sample filling period plus small extension
 | ||||||
|         m_tickMultiplier = m_tickMultiplier < 20 ? 20 : m_tickMultiplier; // not below half a second
 |         m_tickMultiplier /= 20; // greter tick (one per second)
 | ||||||
| 
 |         m_tickMultiplier = m_tickMultiplier < 1 ? 1 : m_tickMultiplier; // not below 1 second
 | ||||||
|         forwardChange = true; |         forwardChange = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -473,7 +491,7 @@ void RemoteOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respon | |||||||
| 
 | 
 | ||||||
| void RemoteOutput::tick() | void RemoteOutput::tick() | ||||||
| { | { | ||||||
|     if (++m_tickCount == m_tickMultiplier) |     if (++m_tickCount == 20) // Every second
 | ||||||
|     { |     { | ||||||
|         QString reportURL; |         QString reportURL; | ||||||
| 
 | 
 | ||||||
| @ -530,22 +548,44 @@ void RemoteOutput::analyzeApiReply(const QJsonObject& jsonObject, const QString& | |||||||
| { | { | ||||||
|     if (jsonObject.contains("RemoteSourceReport")) |     if (jsonObject.contains("RemoteSourceReport")) | ||||||
|     { |     { | ||||||
|  |         MsgReportRemoteData::RemoteData msgRemoteData; | ||||||
|         QJsonObject report = jsonObject["RemoteSourceReport"].toObject(); |         QJsonObject report = jsonObject["RemoteSourceReport"].toObject(); | ||||||
|         m_settings.m_centerFrequency = report["deviceCenterFreq"].toInt(); |         m_settings.m_centerFrequency = report["deviceCenterFreq"].toInt(); | ||||||
|         m_centerFrequency = m_settings.m_centerFrequency * 1000; |         m_centerFrequency = m_settings.m_centerFrequency * 1000; | ||||||
|  |         msgRemoteData.m_centerFrequency = m_centerFrequency; | ||||||
|  |         int queueSize = report["queueSize"].toInt(); | ||||||
|  |         queueSize = queueSize == 0 ? 20 : queueSize; | ||||||
|  |         msgRemoteData.m_queueSize = queueSize; | ||||||
|  |         int queueLength = report["queueLength"].toInt(); | ||||||
|  |         msgRemoteData.m_queueLength = queueLength; | ||||||
|  |         int queueLengthPercent = (queueLength*100)/queueSize; | ||||||
|  |         uint64_t remoteTimestampUs = report["tvSec"].toInt()*1000000ULL + report["tvUSec"].toInt(); | ||||||
|  |         msgRemoteData.m_timestampUs = remoteTimestampUs; | ||||||
|  |         int intRemoteSampleCount = report["samplesCount"].toInt(); | ||||||
|  |         uint32_t remoteSampleCount = intRemoteSampleCount < 0 ? 0 : intRemoteSampleCount; | ||||||
|  |         msgRemoteData.m_sampleCount = remoteSampleCount; | ||||||
|  |         int remoteRate = report["deviceSampleRate"].toInt(); | ||||||
|  |         msgRemoteData.m_sampleRate = remoteRate; | ||||||
|  |         int unrecoverableCount = report["uncorrectableErrorsCount"].toInt(); | ||||||
|  |         msgRemoteData.m_unrecoverableCount = unrecoverableCount; | ||||||
|  |         int recoverableCount = report["correctableErrorsCount"].toInt(); | ||||||
|  |         msgRemoteData.m_recoverableCount = recoverableCount; | ||||||
|  | 
 | ||||||
|  |         if (m_guiMessageQueue) | ||||||
|  |         { | ||||||
|  |             MsgReportRemoteData *msg = MsgReportRemoteData::create(msgRemoteData); | ||||||
|  |             m_guiMessageQueue->push(msg); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (!m_remoteOutputWorker) { |         if (!m_remoteOutputWorker) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         int queueSize = report["queueSize"].toInt(); |         if (++m_greaterTickCount != m_tickMultiplier) { | ||||||
|         queueSize = queueSize == 0 ? 10 : queueSize; |             return; | ||||||
|         int queueLength = report["queueLength"].toInt(); |         } | ||||||
|         int queueLengthPercent = (queueLength*100)/queueSize; |  | ||||||
|         uint64_t remoteTimestampUs = report["tvSec"].toInt()*1000000ULL + report["tvUSec"].toInt(); |  | ||||||
| 
 | 
 | ||||||
|         uint32_t remoteSampleCountDelta, remoteSampleCount; |         uint32_t remoteSampleCountDelta; | ||||||
|         remoteSampleCount = report["samplesCount"].toInt(); |  | ||||||
| 
 | 
 | ||||||
|         if (remoteSampleCount < m_lastRemoteSampleCount) { |         if (remoteSampleCount < m_lastRemoteSampleCount) { | ||||||
|             remoteSampleCountDelta = (0xFFFFFFFFU - m_lastRemoteSampleCount) + remoteSampleCount + 1; |             remoteSampleCountDelta = (0xFFFFFFFFU - m_lastRemoteSampleCount) + remoteSampleCount + 1; | ||||||
| @ -596,11 +636,41 @@ void RemoteOutput::analyzeApiReply(const QJsonObject& jsonObject, const QString& | |||||||
|         m_lastRemoteSampleCount = remoteSampleCount; |         m_lastRemoteSampleCount = remoteSampleCount; | ||||||
|         m_lastSampleCount = sampleCount; |         m_lastSampleCount = sampleCount; | ||||||
|         m_lastQueueLength = queueLength; |         m_lastQueueLength = queueLength; | ||||||
|  |         m_greaterTickCount = 0; | ||||||
|     } |     } | ||||||
|     else if (jsonObject.contains("remoteOutputSettings")) |     else if (jsonObject.contains("remoteOutputSettings")) | ||||||
|     { |     { | ||||||
|         qDebug("RemoteOutput::analyzeApiReply: reply:\n%s", answer.toStdString().c_str()); |         qDebug("RemoteOutput::analyzeApiReply: reply:\n%s", answer.toStdString().c_str()); | ||||||
|     } |     } | ||||||
|  |     else if (jsonObject.contains("version")) | ||||||
|  |     { | ||||||
|  |         MsgReportRemoteFixedData::RemoteData msgRemoteFixedData; | ||||||
|  |         msgRemoteFixedData.m_version = jsonObject["version"].toString(); | ||||||
|  | 
 | ||||||
|  |         if (jsonObject.contains("qtVersion")) { | ||||||
|  |             msgRemoteFixedData.m_qtVersion = jsonObject["qtVersion"].toString(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (jsonObject.contains("architecture")) { | ||||||
|  |             msgRemoteFixedData.m_architecture = jsonObject["architecture"].toString(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (jsonObject.contains("os")) { | ||||||
|  |             msgRemoteFixedData.m_os = jsonObject["os"].toString(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (jsonObject.contains("dspRxBits") && jsonObject.contains("dspTxBits")) | ||||||
|  |         { | ||||||
|  |             msgRemoteFixedData.m_rxBits = jsonObject["dspRxBits"].toInt(); | ||||||
|  |             msgRemoteFixedData.m_txBits = jsonObject["dspTxBits"].toInt(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (m_guiMessageQueue) | ||||||
|  |         { | ||||||
|  |             MsgReportRemoteFixedData *msg = MsgReportRemoteFixedData::create(msgRemoteFixedData); | ||||||
|  |             m_guiMessageQueue->push(msg); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RemoteOutput::sampleRateCorrection(double remoteTimeDeltaUs, double timeDeltaUs, uint32_t remoteSampleCount, uint32_t sampleCount) | void RemoteOutput::sampleRateCorrection(double remoteTimeDeltaUs, double timeDeltaUs, uint32_t remoteSampleCount, uint32_t sampleCount) | ||||||
|  | |||||||
| @ -123,6 +123,100 @@ public: | |||||||
|         { } |         { } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     class MsgConfigureRemoteOutputSampleRate : public Message { | ||||||
|  |         MESSAGE_CLASS_DECLARATION | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  |         int getSampleRate() const { return m_sampleRate; } | ||||||
|  | 
 | ||||||
|  |         static MsgConfigureRemoteOutputSampleRate* create(int sampleRate) { | ||||||
|  |             return new MsgConfigureRemoteOutputSampleRate(sampleRate); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         int m_sampleRate; | ||||||
|  | 
 | ||||||
|  |         MsgConfigureRemoteOutputSampleRate(int sampleRate) : | ||||||
|  |             Message(), | ||||||
|  |             m_sampleRate(sampleRate) | ||||||
|  |         { } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     class MsgReportRemoteData : public Message { | ||||||
|  |         MESSAGE_CLASS_DECLARATION | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  |         struct RemoteData | ||||||
|  |         { | ||||||
|  |             quint64 m_centerFrequency; //!< Center frequency where the stream is placed
 | ||||||
|  |             int m_sampleRate;          //!< Sample rate requested by remote
 | ||||||
|  |             int m_queueSize;           //!< Remote data read queue size
 | ||||||
|  |             int m_queueLength;         //!< Remote data queue length
 | ||||||
|  |             int m_unrecoverableCount;  //!< Number of unrecoverable errors from FEC
 | ||||||
|  |             int m_recoverableCount;    //!< Number of recoverable errors from FEC
 | ||||||
|  |             uint64_t m_timestampUs;    //!< Unix time stamp of request in microseconds
 | ||||||
|  |             uint32_t m_sampleCount;    //!< Number of samples processed in the remote at request time
 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         const RemoteData& getData() const { return m_remoteData; } | ||||||
|  | 
 | ||||||
|  |         static MsgReportRemoteData* create(const RemoteData& remoteData) { | ||||||
|  |             return new MsgReportRemoteData(remoteData); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         RemoteData m_remoteData; | ||||||
|  | 
 | ||||||
|  |         MsgReportRemoteData(const RemoteData& remoteData) : | ||||||
|  |             Message(), | ||||||
|  |             m_remoteData(remoteData) | ||||||
|  |         {} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     class MsgReportRemoteFixedData : public Message { | ||||||
|  |         MESSAGE_CLASS_DECLARATION | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  |         struct RemoteData | ||||||
|  |         { | ||||||
|  |             QString m_version;      //!< Remote SDRangel version
 | ||||||
|  |             QString m_qtVersion;    //!< Remote Qt version used to build SDRangel
 | ||||||
|  |             QString m_architecture; //!< Remote CPU architecture
 | ||||||
|  |             QString m_os;           //!< Remote O/S
 | ||||||
|  |             int     m_rxBits;       //!< Number of bits used for I or Q sample on Rx side
 | ||||||
|  |             int     m_txBits;       //!< Number of bits used for I or Q sample on Tx side
 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         const RemoteData& getData() const { return m_remoteData; } | ||||||
|  | 
 | ||||||
|  |         static MsgReportRemoteFixedData* create(const RemoteData& remoteData) { | ||||||
|  |             return new MsgReportRemoteFixedData(remoteData); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         RemoteData m_remoteData; | ||||||
|  | 
 | ||||||
|  |         MsgReportRemoteFixedData(const RemoteData& remoteData) : | ||||||
|  |             Message(), | ||||||
|  |             m_remoteData(remoteData) | ||||||
|  |         {} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     class MsgRequestFixedData : public Message { | ||||||
|  |         MESSAGE_CLASS_DECLARATION | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  |         static MsgRequestFixedData* create() { | ||||||
|  |             return new MsgRequestFixedData(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         MsgRequestFixedData() : | ||||||
|  |             Message() | ||||||
|  |         {} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	RemoteOutput(DeviceAPI *deviceAPI); | 	RemoteOutput(DeviceAPI *deviceAPI); | ||||||
| 	virtual ~RemoteOutput(); | 	virtual ~RemoteOutput(); | ||||||
| 	virtual void destroy(); | 	virtual void destroy(); | ||||||
| @ -186,8 +280,9 @@ private: | |||||||
| 	QString m_deviceDescription; | 	QString m_deviceDescription; | ||||||
| 	std::time_t m_startingTimeStamp; | 	std::time_t m_startingTimeStamp; | ||||||
| 	const QTimer& m_masterTimer; | 	const QTimer& m_masterTimer; | ||||||
| 	uint32_t m_tickCount; | 	uint32_t m_tickCount; // for 50 ms timer
 | ||||||
|     uint32_t m_tickMultiplier; |     uint32_t m_greaterTickCount; // for 1 s derived timer
 | ||||||
|  |     uint32_t m_tickMultiplier; // for greater tick count
 | ||||||
| 
 | 
 | ||||||
|     QNetworkAccessManager *m_networkManager; |     QNetworkAccessManager *m_networkManager; | ||||||
|     QNetworkRequest m_networkRequest; |     QNetworkRequest m_networkRequest; | ||||||
|  | |||||||
| @ -20,9 +20,6 @@ | |||||||
| #include <QDateTime> | #include <QDateTime> | ||||||
| #include <QString> | #include <QString> | ||||||
| #include <QMessageBox> | #include <QMessageBox> | ||||||
| #include <QNetworkAccessManager> |  | ||||||
| #include <QNetworkReply> |  | ||||||
| #include <QJsonParseError> |  | ||||||
| 
 | 
 | ||||||
| #include <boost/algorithm/string.hpp> | #include <boost/algorithm/string.hpp> | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| @ -51,7 +48,7 @@ RemoteOutputSinkGui::RemoteOutputSinkGui(DeviceUISet *deviceUISet, QWidget* pare | |||||||
| 	ui(new Ui::RemoteOutputGui), | 	ui(new Ui::RemoteOutputGui), | ||||||
| 	m_deviceUISet(deviceUISet), | 	m_deviceUISet(deviceUISet), | ||||||
| 	m_settings(), | 	m_settings(), | ||||||
| 	m_deviceSampleSink(0), | 	m_remoteOutput(0), | ||||||
| 	m_deviceCenterFrequency(0), | 	m_deviceCenterFrequency(0), | ||||||
| 	m_samplesCount(0), | 	m_samplesCount(0), | ||||||
| 	m_tickCount(0), | 	m_tickCount(0), | ||||||
| @ -83,13 +80,10 @@ RemoteOutputSinkGui::RemoteOutputSinkGui(DeviceUISet *deviceUISet, QWidget* pare | |||||||
| 	connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); | 	connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); | ||||||
| 	m_statusTimer.start(500); | 	m_statusTimer.start(500); | ||||||
| 
 | 
 | ||||||
| 	m_deviceSampleSink = (RemoteOutput*) m_deviceUISet->m_deviceAPI->getSampleSink(); | 	m_remoteOutput = (RemoteOutput*) m_deviceUISet->m_deviceAPI->getSampleSink(); | ||||||
| 
 | 
 | ||||||
| 	connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); | 	connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); | ||||||
| 
 | 
 | ||||||
| 	m_networkManager = new QNetworkAccessManager(); |  | ||||||
| 	connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); |  | ||||||
| 
 |  | ||||||
| 	m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency); | 	m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency); | ||||||
| 
 | 
 | ||||||
|     m_time.start(); |     m_time.start(); | ||||||
| @ -105,8 +99,6 @@ RemoteOutputSinkGui::RemoteOutputSinkGui(DeviceUISet *deviceUISet, QWidget* pare | |||||||
| 
 | 
 | ||||||
| RemoteOutputSinkGui::~RemoteOutputSinkGui() | RemoteOutputSinkGui::~RemoteOutputSinkGui() | ||||||
| { | { | ||||||
|     disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); |  | ||||||
|     delete m_networkManager; |  | ||||||
| 	delete ui; | 	delete ui; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -171,6 +163,18 @@ bool RemoteOutputSinkGui::handleMessage(const Message& message) | |||||||
|         ui->startStop->setChecked(notif.getStartStop()); |         ui->startStop->setChecked(notif.getStartStop()); | ||||||
|         blockApplySettings(false); |         blockApplySettings(false); | ||||||
|         return true; |         return true; | ||||||
|  |     } | ||||||
|  |     else if (RemoteOutput::MsgReportRemoteData::match(message)) | ||||||
|  |     { | ||||||
|  |         const RemoteOutput::MsgReportRemoteData& report = (const RemoteOutput::MsgReportRemoteData&) message; | ||||||
|  |         displayRemoteData(report.getData()); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     else if (RemoteOutput::MsgReportRemoteFixedData::match(message)) | ||||||
|  |     { | ||||||
|  |         const RemoteOutput::MsgReportRemoteFixedData& report = (const RemoteOutput::MsgReportRemoteFixedData&) message; | ||||||
|  |         displayRemoteFixedData(report.getData()); | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -239,7 +243,7 @@ void RemoteOutputSinkGui::updateHardware() | |||||||
| { | { | ||||||
|     qDebug() << "RemoteOutputSinkGui::updateHardware"; |     qDebug() << "RemoteOutputSinkGui::updateHardware"; | ||||||
|     RemoteOutput::MsgConfigureRemoteOutput* message = RemoteOutput::MsgConfigureRemoteOutput::create(m_settings, m_forceSettings); |     RemoteOutput::MsgConfigureRemoteOutput* message = RemoteOutput::MsgConfigureRemoteOutput::create(m_settings, m_forceSettings); | ||||||
|     m_deviceSampleSink->getInputMessageQueue()->push(message); |     m_remoteOutput->getInputMessageQueue()->push(message); | ||||||
|     m_forceSettings = false; |     m_forceSettings = false; | ||||||
|     m_updateTimer.stop(); |     m_updateTimer.stop(); | ||||||
| } | } | ||||||
| @ -323,9 +327,8 @@ void RemoteOutputSinkGui::on_apiAddress_returnPressed() | |||||||
|     m_settings.m_apiAddress = ui->apiAddress->text(); |     m_settings.m_apiAddress = ui->apiAddress->text(); | ||||||
|     sendSettings(); |     sendSettings(); | ||||||
| 
 | 
 | ||||||
|     QString infoURL = QString("http://%1:%2/sdrangel").arg(m_settings.m_apiAddress).arg(m_settings.m_apiPort); |     RemoteOutput::MsgRequestFixedData *msg = RemoteOutput::MsgRequestFixedData::create(); | ||||||
|     m_networkRequest.setUrl(QUrl(infoURL)); |     m_remoteOutput->getInputMessageQueue()->push(msg); | ||||||
|     m_networkManager->get(m_networkRequest); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RemoteOutputSinkGui::on_apiPort_returnPressed() | void RemoteOutputSinkGui::on_apiPort_returnPressed() | ||||||
| @ -341,9 +344,8 @@ void RemoteOutputSinkGui::on_apiPort_returnPressed() | |||||||
| 
 | 
 | ||||||
|     sendSettings(); |     sendSettings(); | ||||||
| 
 | 
 | ||||||
|     QString infoURL = QString("http://%1:%2/sdrangel").arg(m_settings.m_apiAddress).arg(m_settings.m_apiPort); |     RemoteOutput::MsgRequestFixedData *msg = RemoteOutput::MsgRequestFixedData::create(); | ||||||
|     m_networkRequest.setUrl(QUrl(infoURL)); |     m_remoteOutput->getInputMessageQueue()->push(msg); | ||||||
|     m_networkManager->get(m_networkRequest); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RemoteOutputSinkGui::on_dataAddress_returnPressed() | void RemoteOutputSinkGui::on_dataAddress_returnPressed() | ||||||
| @ -381,9 +383,8 @@ void RemoteOutputSinkGui::on_apiApplyButton_clicked(bool checked) | |||||||
| 
 | 
 | ||||||
|     sendSettings(); |     sendSettings(); | ||||||
| 
 | 
 | ||||||
|     QString infoURL = QString("http://%1:%2/sdrangel").arg(m_settings.m_apiAddress).arg(m_settings.m_apiPort); |     RemoteOutput::MsgRequestFixedData *msg = RemoteOutput::MsgRequestFixedData::create(); | ||||||
|     m_networkRequest.setUrl(QUrl(infoURL)); |     m_remoteOutput->getInputMessageQueue()->push(msg); | ||||||
|     m_networkManager->get(m_networkRequest); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RemoteOutputSinkGui::on_dataApplyButton_clicked(bool checked) | void RemoteOutputSinkGui::on_dataApplyButton_clicked(bool checked) | ||||||
| @ -407,7 +408,7 @@ void RemoteOutputSinkGui::on_startStop_toggled(bool checked) | |||||||
|     if (m_doApplySettings) |     if (m_doApplySettings) | ||||||
|     { |     { | ||||||
|         RemoteOutput::MsgStartStop *message = RemoteOutput::MsgStartStop::create(checked); |         RemoteOutput::MsgStartStop *message = RemoteOutput::MsgStartStop::create(checked); | ||||||
|         m_deviceSampleSink->getInputMessageQueue()->push(message); |         m_remoteOutput->getInputMessageQueue()->push(message); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -457,146 +458,62 @@ void RemoteOutputSinkGui::displayEventTimer() | |||||||
| 
 | 
 | ||||||
| void RemoteOutputSinkGui::tick() | void RemoteOutputSinkGui::tick() | ||||||
| { | { | ||||||
|     if (++m_tickCount == 20) // once per second
 |  | ||||||
| 	{ |  | ||||||
|         QString reportURL; |  | ||||||
| 
 |  | ||||||
|         reportURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/report") |  | ||||||
|                 .arg(m_settings.m_apiAddress) |  | ||||||
|                 .arg(m_settings.m_apiPort) |  | ||||||
|                 .arg(m_settings.m_deviceIndex) |  | ||||||
|                 .arg(m_settings.m_channelIndex); |  | ||||||
| 	    m_networkRequest.setUrl(QUrl(reportURL)); |  | ||||||
| 	    m_networkManager->get(m_networkRequest); |  | ||||||
| 
 |  | ||||||
|         displayEventTimer(); |  | ||||||
| 
 |  | ||||||
|         m_tickCount = 0; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RemoteOutputSinkGui::networkManagerFinished(QNetworkReply *reply) | void RemoteOutputSinkGui::displayRemoteData(const RemoteOutput::MsgReportRemoteData::RemoteData& remoteData) | ||||||
| { | { | ||||||
|     if (reply->error()) |     m_deviceCenterFrequency = remoteData.m_centerFrequency; | ||||||
|     { |     m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency); | ||||||
|         ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }"); |     ui->centerFrequency->setText(QString("%L1").arg(m_deviceCenterFrequency)); | ||||||
|         ui->statusText->setText(reply->errorString()); |     ui->remoteRateText->setText(tr("%1k").arg((float)(remoteData.m_sampleRate) / 1000)); | ||||||
|     } |     QString queueLengthText = QString("%1/%2").arg(remoteData.m_queueLength).arg(remoteData.m_queueSize); | ||||||
|     else |     ui->queueLengthText->setText(queueLengthText); | ||||||
|     { |     int queueLengthPercent = (remoteData.m_queueLength*100)/remoteData.m_queueSize; | ||||||
|         QString answer = reply->readAll(); |     ui->queueLengthGauge->setValue(queueLengthPercent); | ||||||
| 
 | 
 | ||||||
|         try |     if (!m_resetCounts) | ||||||
|         { |     { | ||||||
|             QByteArray jsonBytes(answer.toStdString().c_str()); |         int recoverableCountDelta = remoteData.m_recoverableCount - m_lastCountRecovered; | ||||||
|             QJsonParseError error; |         int unrecoverableCountDelta = remoteData.m_unrecoverableCount - m_lastCountUnrecoverable; | ||||||
|             QJsonDocument doc = QJsonDocument::fromJson(jsonBytes, &error); |         displayEventStatus(recoverableCountDelta, unrecoverableCountDelta); | ||||||
| 
 |         m_countRecovered += recoverableCountDelta; | ||||||
|             if (error.error == QJsonParseError::NoError) |         m_countUnrecoverable += unrecoverableCountDelta; | ||||||
|             { |         displayEventCounts(); | ||||||
|                 ui->apiAddressLabel->setStyleSheet("QLabel { background-color : green; }"); |  | ||||||
|                 ui->statusText->setText(QString("API OK")); |  | ||||||
|                 analyzeApiReply(doc.object()); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }"); |  | ||||||
|                 QString errorMsg = QString("Reply JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset); |  | ||||||
|                 ui->statusText->setText(QString("JSON error. See log")); |  | ||||||
|                 qInfo().noquote() << "RemoteOutputSinkGui::networkManagerFinished" << errorMsg; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         catch (const std::exception& ex) |  | ||||||
|         { |  | ||||||
|             ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }"); |  | ||||||
|             QString errorMsg = QString("Error parsing request: ") + ex.what(); |  | ||||||
|             ui->statusText->setText("Error parsing request. See log for details"); |  | ||||||
|             qInfo().noquote() << "RemoteOutputSinkGui::networkManagerFinished" << errorMsg; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     reply->deleteLater(); |     uint32_t sampleCountDelta; | ||||||
|  | 
 | ||||||
|  |     if (remoteData.m_sampleCount < m_lastSampleCount) { | ||||||
|  |         sampleCountDelta = (0xFFFFFFFFU - m_lastSampleCount) + remoteData.m_sampleCount + 1; | ||||||
|  |     } else { | ||||||
|  |         sampleCountDelta = remoteData.m_sampleCount - m_lastSampleCount; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (sampleCountDelta == 0) | ||||||
|  |     { | ||||||
|  |         ui->allFramesDecoded->setStyleSheet("QToolButton { background-color : blue; }"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     double remoteStreamRate = sampleCountDelta*1e6 / (double) (remoteData.m_timestampUs - m_lastTimestampUs); | ||||||
|  | 
 | ||||||
|  |     if (remoteStreamRate != 0) { | ||||||
|  |         ui->remoteStreamRateText->setText(QString("%1").arg(remoteStreamRate, 0, 'f', 0)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     m_resetCounts = false; | ||||||
|  |     m_lastCountRecovered = remoteData.m_recoverableCount; | ||||||
|  |     m_lastCountUnrecoverable = remoteData.m_unrecoverableCount; | ||||||
|  |     m_lastSampleCount = remoteData.m_sampleCount; | ||||||
|  |     m_lastTimestampUs = remoteData.m_timestampUs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RemoteOutputSinkGui::analyzeApiReply(const QJsonObject& jsonObject) | void RemoteOutputSinkGui::displayRemoteFixedData(const RemoteOutput::MsgReportRemoteFixedData::RemoteData& remoteData) | ||||||
| { | { | ||||||
|     QString infoLine; |     QString infoLine = "v" + remoteData.m_version; | ||||||
| 
 |     infoLine += " Qt" + remoteData.m_qtVersion; | ||||||
|     if (jsonObject.contains("RemoteSourceReport")) |     infoLine += " " + remoteData.m_architecture; | ||||||
|     { |     infoLine += " " + remoteData.m_os; | ||||||
|         QJsonObject report = jsonObject["RemoteSourceReport"].toObject(); |     infoLine +=  QString(" %1/%2b").arg(remoteData.m_rxBits).arg(remoteData.m_txBits); | ||||||
|         m_deviceCenterFrequency = report["deviceCenterFreq"].toInt() * 1000; |  | ||||||
|         m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency); |  | ||||||
|         ui->centerFrequency->setText(QString("%L1").arg(m_deviceCenterFrequency)); |  | ||||||
|         int remoteRate = report["deviceSampleRate"].toInt(); |  | ||||||
|         ui->remoteRateText->setText(tr("%1k").arg((float)(remoteRate) / 1000)); |  | ||||||
|         int queueSize = report["queueSize"].toInt(); |  | ||||||
|         queueSize = queueSize == 0 ? 10 : queueSize; |  | ||||||
|         int queueLength = report["queueLength"].toInt(); |  | ||||||
|         QString queueLengthText = QString("%1/%2").arg(queueLength).arg(queueSize); |  | ||||||
|         ui->queueLengthText->setText(queueLengthText); |  | ||||||
|         int queueLengthPercent = (queueLength*100)/queueSize; |  | ||||||
|         ui->queueLengthGauge->setValue(queueLengthPercent); |  | ||||||
|         int unrecoverableCount = report["uncorrectableErrorsCount"].toInt(); |  | ||||||
|         int recoverableCount = report["correctableErrorsCount"].toInt(); |  | ||||||
|         uint64_t timestampUs = report["tvSec"].toInt()*1000000ULL + report["tvUSec"].toInt(); |  | ||||||
| 
 |  | ||||||
|         if (!m_resetCounts) |  | ||||||
|         { |  | ||||||
|             int recoverableCountDelta = recoverableCount - m_lastCountRecovered; |  | ||||||
|             int unrecoverableCountDelta = unrecoverableCount - m_lastCountUnrecoverable; |  | ||||||
|             displayEventStatus(recoverableCountDelta, unrecoverableCountDelta); |  | ||||||
|             m_countRecovered += recoverableCountDelta; |  | ||||||
|             m_countUnrecoverable += unrecoverableCountDelta; |  | ||||||
|             displayEventCounts(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         uint32_t sampleCountDelta, sampleCount; |  | ||||||
|         sampleCount = report["samplesCount"].toInt(); |  | ||||||
| 
 |  | ||||||
|         if (sampleCount < m_lastSampleCount) { |  | ||||||
|             sampleCountDelta = (0xFFFFFFFFU - m_lastSampleCount) + sampleCount + 1; |  | ||||||
|         } else { |  | ||||||
|             sampleCountDelta = sampleCount - m_lastSampleCount; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (sampleCountDelta == 0) |  | ||||||
|         { |  | ||||||
|             ui->allFramesDecoded->setStyleSheet("QToolButton { background-color : blue; }"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         double remoteStreamRate = sampleCountDelta*1e6 / (double) (timestampUs - m_lastTimestampUs); |  | ||||||
| 
 |  | ||||||
|         if (remoteStreamRate != 0) { |  | ||||||
|             ui->remoteStreamRateText->setText(QString("%1").arg(remoteStreamRate, 0, 'f', 0)); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         m_resetCounts = false; |  | ||||||
|         m_lastCountRecovered = recoverableCount; |  | ||||||
|         m_lastCountUnrecoverable = unrecoverableCount; |  | ||||||
|         m_lastSampleCount = sampleCount; |  | ||||||
|         m_lastTimestampUs = timestampUs; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (jsonObject.contains("version")) { |  | ||||||
|         infoLine = "v" + jsonObject["version"].toString(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (jsonObject.contains("qtVersion")) { |  | ||||||
|         infoLine += " Qt" + jsonObject["qtVersion"].toString(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (jsonObject.contains("architecture")) { |  | ||||||
|         infoLine += " " + jsonObject["architecture"].toString(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (jsonObject.contains("os")) { |  | ||||||
|         infoLine += " " + jsonObject["os"].toString(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (jsonObject.contains("dspRxBits") && jsonObject.contains("dspTxBits")) { |  | ||||||
|         infoLine +=  QString(" %1/%2b").arg(jsonObject["dspRxBits"].toInt()).arg(jsonObject["dspTxBits"].toInt()); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (infoLine.size() > 0) { |     if (infoLine.size() > 0) { | ||||||
|         ui->infoText->setText(infoLine); |         ui->infoText->setText(infoLine); | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ | |||||||
| #include <QTimer> | #include <QTimer> | ||||||
| #include <QElapsedTimer> | #include <QElapsedTimer> | ||||||
| #include <QWidget> | #include <QWidget> | ||||||
| #include <QNetworkRequest> |  | ||||||
| 
 | 
 | ||||||
| #include "device/devicegui.h" | #include "device/devicegui.h" | ||||||
| #include "util/messagequeue.h" | #include "util/messagequeue.h" | ||||||
| @ -32,9 +31,6 @@ | |||||||
| #include "remoteoutput.h" | #include "remoteoutput.h" | ||||||
| #include "remoteoutputsettings.h" | #include "remoteoutputsettings.h" | ||||||
| 
 | 
 | ||||||
| class QNetworkAccessManager; |  | ||||||
| class QNetworkReply; |  | ||||||
| class QJsonObject; |  | ||||||
| class DeviceSampleSink; | class DeviceSampleSink; | ||||||
| class DeviceUISet; | class DeviceUISet; | ||||||
| 
 | 
 | ||||||
| @ -90,7 +86,7 @@ private: | |||||||
| 	RemoteOutputSettings m_controlSettings; //!< settings last sent to device via control port
 | 	RemoteOutputSettings m_controlSettings; //!< settings last sent to device via control port
 | ||||||
| 	QTimer m_updateTimer; | 	QTimer m_updateTimer; | ||||||
|     QTimer m_statusTimer; |     QTimer m_statusTimer; | ||||||
| 	DeviceSampleSink* m_deviceSampleSink; | 	DeviceSampleSink* m_remoteOutput; | ||||||
|     int m_sampleRate; |     int m_sampleRate; | ||||||
|     quint64 m_deviceCenterFrequency; //!< Center frequency in device
 |     quint64 m_deviceCenterFrequency; //!< Center frequency in device
 | ||||||
| 	int m_samplesCount; | 	int m_samplesCount; | ||||||
| @ -115,19 +111,17 @@ private: | |||||||
| 
 | 
 | ||||||
|     MessageQueue m_inputMessageQueue; |     MessageQueue m_inputMessageQueue; | ||||||
| 
 | 
 | ||||||
|     QNetworkAccessManager *m_networkManager; |  | ||||||
|     QNetworkRequest m_networkRequest; |  | ||||||
| 
 |  | ||||||
|     void blockApplySettings(bool block); |     void blockApplySettings(bool block); | ||||||
| 	void displaySettings(); | 	void displaySettings(); | ||||||
| 	void displayTime(); | 	void displayTime(); | ||||||
|  |     void displayRemoteData(const RemoteOutput::MsgReportRemoteData::RemoteData& remoteData); | ||||||
|  |     void displayRemoteFixedData(const RemoteOutput::MsgReportRemoteFixedData::RemoteData& remoteData); | ||||||
|     void sendControl(bool force = false); |     void sendControl(bool force = false); | ||||||
| 	void sendSettings(); | 	void sendSettings(); | ||||||
| 	void updateSampleRate(); | 	void updateSampleRate(); | ||||||
| 	void displayEventCounts(); | 	void displayEventCounts(); | ||||||
| 	void displayEventStatus(int recoverableCount, int unrecoverableCount); | 	void displayEventStatus(int recoverableCount, int unrecoverableCount); | ||||||
|     void displayEventTimer(); |     void displayEventTimer(); | ||||||
|     void analyzeApiReply(const QJsonObject& jsonObject); |  | ||||||
| 	bool handleMessage(const Message& message); | 	bool handleMessage(const Message& message); | ||||||
| 
 | 
 | ||||||
| private slots: | private slots: | ||||||
| @ -147,7 +141,6 @@ private slots: | |||||||
|     void updateHardware(); |     void updateHardware(); | ||||||
|     void updateStatus(); |     void updateStatus(); | ||||||
| 	void tick(); | 	void tick(); | ||||||
| 	void networkManagerFinished(QNetworkReply *reply); |  | ||||||
|     void openDeviceSettingsDialog(const QPoint& p); |     void openDeviceSettingsDialog(const QPoint& p); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user