22 #include <QMessageBox> 23 #include <QNetworkAccessManager> 24 #include <QNetworkReply> 25 #include <QJsonParseError> 27 #include <boost/algorithm/string.hpp> 28 #include <boost/lexical_cast.hpp> 30 #include "ui_remoteoutputgui.h" 51 ui(new
Ui::RemoteOutputGui),
52 m_deviceUISet(deviceUISet),
54 m_deviceSampleSink(0),
55 m_deviceCenterFrequency(0),
58 m_nbSinceLastFlowCheck(0),
59 m_lastEngineState(
DeviceAPI::StNotStarted),
60 m_doApplySettings(true),
77 ui->centerFrequency->setValueRange(7, 0, pow(10,7));
80 ui->sampleRate->setValueRange(7, 32000U, 9000000U);
82 ui->apiAddressLabel->setStyleSheet(
"QLabel { background:rgb(79,79,79); }");
103 connect(startStopRightClickEnabler, SIGNAL(rightClick(
const QPoint &)),
this, SLOT(
openDeviceSettingsDialog(
const QPoint &)));
204 qDebug(
"RemoteOutputSinkGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->
getSampleRate(), notif->
getCenterFrequency());
226 int samplesPerBlock = RemoteNbBytesPerBlock / (
SDR_RX_SAMP_SZ <= 16 ? 4 : 8);
228 ui->txDelayText->setToolTip(tr(
"%1 us").
arg(QString::number(delay*1e6,
'f', 0)));
242 ui->nominalNbBlocksText->setText(tr(
"%1/%2").
arg(s0).
arg(s1));
262 qDebug() <<
"RemoteOutputSinkGui::updateHardware";
278 ui->startStop->setStyleSheet(
"QToolButton { background:rgb(79,79,79); }");
281 ui->startStop->setStyleSheet(
"QToolButton { background-color : blue; }");
284 ui->startStop->setStyleSheet(
"QToolButton { background-color : green; }");
287 ui->startStop->setStyleSheet(
"QToolButton { background-color : red; }");
308 ui->txDelayText->setText(tr(
"%1").
arg(value));
316 int nbOriginalBlocks = 128;
317 int nbFECBlocks = value;
318 QString s = QString::number(nbOriginalBlocks + nbFECBlocks,
'f', 0);
319 QString s1 = QString::number(nbFECBlocks,
'f', 0);
320 ui->nominalNbBlocksText->setText(tr(
"%1/%2").
arg(s).
arg(s1));
328 int deviceIndex =
ui->deviceIndex->text().toInt(&dataOk);
330 if ((!dataOk) || (deviceIndex < 0)) {
342 int channelIndex =
ui->channelIndex->text().toInt(&dataOk);
344 if ((!dataOk) || (channelIndex < 0)) {
366 int apiPort =
ui->apiPort->text().toInt(&dataOk);
368 if((!dataOk) || (apiPort < 1024) || (apiPort > 65535)) {
390 int dataPort =
ui->dataPort->text().toInt(&dataOk);
392 if((!dataOk) || (dataPort < 1024) || (dataPort > 65535)) {
407 int apiPort =
ui->apiPort->text().toInt(&apiOk);
409 if((apiOk) && (apiPort >= 1024) && (apiPort < 65535))
427 int udpDataPort =
ui->dataPort->text().toInt(&dataOk);
429 if((dataOk) && (udpDataPort >= 1024) && (udpDataPort < 65535))
459 ui->eventUnrecText->setText(nstr);
461 ui->eventRecText->setText(nstr);
467 if (unrecoverableCount == 0)
469 if (recoverableCount == 0) {
470 ui->allFramesDecoded->setStyleSheet(
"QToolButton { background-color : green; }");
472 ui->allFramesDecoded->setStyleSheet(
"QToolButton { background:rgb(79,79,79); }");
477 ui->allFramesDecoded->setStyleSheet(
"QToolButton { background-color : red; }");
483 int elapsedTimeMillis =
m_time.elapsed();
484 QTime recordLength(0, 0, 0, 0);
485 recordLength = recordLength.addSecs(elapsedTimeMillis/1000);
486 QString s_time = recordLength.toString(
"HH:mm:ss");
487 ui->eventCountsTimeText->setText(s_time);
496 reportURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/report")
514 ui->apiAddressLabel->setStyleSheet(
"QLabel { background:rgb(79,79,79); }");
515 ui->statusText->setText(reply->errorString());
519 QString answer = reply->readAll();
523 QByteArray jsonBytes(answer.toStdString().c_str());
524 QJsonParseError error;
525 QJsonDocument doc = QJsonDocument::fromJson(jsonBytes, &error);
527 if (error.error == QJsonParseError::NoError)
529 ui->apiAddressLabel->setStyleSheet(
"QLabel { background-color : green; }");
530 ui->statusText->setText(QString(
"API OK"));
535 ui->apiAddressLabel->setStyleSheet(
"QLabel { background:rgb(79,79,79); }");
536 QString errorMsg = QString(
"Reply JSON error: ") + error.errorString() + QString(
" at offset ") + QString::number(error.offset);
537 ui->statusText->setText(QString(
"JSON error. See log"));
538 qInfo().noquote() <<
"RemoteOutputSinkGui::networkManagerFinished" << errorMsg;
541 catch (
const std::exception& ex)
543 ui->apiAddressLabel->setStyleSheet(
"QLabel { background:rgb(79,79,79); }");
544 QString errorMsg = QString(
"Error parsing request: ") + ex.what();
545 ui->statusText->setText(
"Error parsing request. See log for details");
546 qInfo().noquote() <<
"RemoteOutputSinkGui::networkManagerFinished" << errorMsg;
554 if (jsonObject.contains(
"RemoteSourceReport"))
556 QJsonObject report = jsonObject[
"RemoteSourceReport"].toObject();
560 int remoteRate = report[
"deviceSampleRate"].toInt();
561 ui->remoteRateText->setText(tr(
"%1k").
arg((
float)(remoteRate) / 1000));
562 int queueSize = report[
"queueSize"].toInt();
563 queueSize = queueSize == 0 ? 10 : queueSize;
564 int queueLength = report[
"queueLength"].toInt();
565 QString queueLengthText = QString(
"%1/%2").arg(queueLength).arg(queueSize);
566 ui->queueLengthText->setText(queueLengthText);
567 int queueLengthPercent = (queueLength*100)/queueSize;
568 ui->queueLengthGauge->setValue(queueLengthPercent);
569 int unrecoverableCount = report[
"uncorrectableErrorsCount"].toInt();
570 int recoverableCount = report[
"correctableErrorsCount"].toInt();
571 uint64_t timestampUs = report[
"tvSec"].toInt()*1000000ULL + report[
"tvUSec"].toInt();
583 uint32_t sampleCountDelta, sampleCount;
584 sampleCount = report[
"samplesCount"].toInt();
592 if (sampleCountDelta == 0)
594 ui->allFramesDecoded->setStyleSheet(
"QToolButton { background-color : blue; }");
597 double remoteStreamRate = sampleCountDelta*1e6 / (double) (timestampUs -
m_lastTimestampUs);
599 if (remoteStreamRate != 0) {
600 ui->remoteStreamRateText->setText(QString(
"%1").
arg(remoteStreamRate, 0,
'f', 0));
610 if (jsonObject.contains(
"version")) {
611 infoLine =
"v" + jsonObject[
"version"].toString();
614 if (jsonObject.contains(
"qtVersion")) {
615 infoLine +=
" Qt" + jsonObject[
"qtVersion"].toString();
618 if (jsonObject.contains(
"architecture")) {
619 infoLine +=
" " + jsonObject[
"architecture"].toString();
622 if (jsonObject.contains(
"os")) {
623 infoLine +=
" " + jsonObject[
"os"].toString();
626 if (jsonObject.contains(
"dspRxBits") && jsonObject.contains(
"dspTxBits")) {
627 infoLine += QString(
" %1/%2b").arg(jsonObject[
"dspRxBits"].toInt()).arg(jsonObject[
"dspTxBits"].toInt());
630 if (infoLine.size() > 0) {
631 ui->infoText->setText(infoLine);
void on_apiAddress_returnPressed()
Message * pop()
Pop message from queue.
const QString & getReverseAPIAddress() const
void analyzeApiReply(const QJsonObject &jsonObject)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setSampleRate(qint32 sampleRate)
void setUseReverseAPI(bool useReverseAPI)
void on_channelIndex_returnPressed()
void displayEventStatus(int recoverableCount, int unrecoverableCount)
void displayEventCounts()
void networkManagerFinished(QNetworkReply *reply)
QPalette m_paletteGreenText
uint16_t getReverseAPIDeviceIndex() const
const QTimer & getMasterTimer() const
This is the DSPEngine master timer.
QString errorMessage()
Last error message from the device engine.
void on_eventCountsReset_clicked(bool checked)
DeviceSampleSink * getSampleSink()
Return pointer to the device sample sink (single Tx) or nullptr.
bool deserialize(const QByteArray &data)
RemoteOutputSettings m_settings
current settings
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
GLSpectrum * getSpectrum()
Direct spectrum getter.
uint16_t m_reverseAPIDeviceIndex
uint32_t m_lastCountRecovered
engine is before initialization
MessageQueue m_inputMessageQueue
qint64 getCenterFrequency() const
EngineState state() const
Return the state of the device engine corresponding to the stream type.
QString m_reverseAPIAddress
MessageQueue * getInputMessageQueue()
static MsgStartStop * create(bool startStop)
uint16_t getReverseAPIPort() const
QNetworkRequest m_networkRequest
void on_dataApplyButton_clicked(bool checked)
void on_startStop_toggled(bool checked)
uint16_t m_reverseAPIPort
virtual bool handleMessage(const Message &message)
void on_deviceIndex_returnPressed()
DeviceSampleSink * m_deviceSampleSink
static bool match(const Message *message)
RemoteOutputSinkGui(DeviceUISet *deviceUISet, QWidget *parent=0)
void handleInputMessages()
QByteArray serialize() const
void openDeviceSettingsDialog(const QPoint &p)
void on_dataAddress_returnPressed()
uint64_t m_lastTimestampUs
void on_sampleRate_changed(quint64 value)
uint32_t m_lastCountUnrecoverable
void on_nbFECBlocks_valueChanged(int value)
void on_apiPort_returnPressed()
uint32_t m_countRecovered
bool getStartStop() const
uint32_t m_countUnrecoverable
QPalette m_paletteRedText
uint32_t m_lastSampleCount
int getSampleRate() const
void setCenterFrequency(qint64 frequency)
QByteArray serialize() const
void setReverseAPIAddress(const QString &address)
void on_txDelay_valueChanged(int value)
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
void on_apiApplyButton_clicked(bool checked)
void on_dataPort_returnPressed()
void setReverseAPIPort(uint16_t port)
quint64 m_deviceCenterFrequency
Center frequency in device.
void setName(const QString &name)
bool useReverseAPI() const
virtual ~RemoteOutputSinkGui()
DeviceUISet * m_deviceUISet
bool deserialize(const QByteArray &data)
void blockApplySettings(bool block)
QNetworkAccessManager * m_networkManager
QPalette m_paletteWhiteText
void updateTxDelayTooltip()
unsigned __int64 uint64_t