SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Classes | Public Member Functions | Private Slots | Private Member Functions | Private Attributes | List of all members
TestMI Class Reference

#include <testmi.h>

+ Inheritance diagram for TestMI:
+ Collaboration diagram for TestMI:

Classes

struct  DeviceSettingsKeys
 
class  MsgConfigureTestSource
 
class  MsgFileRecord
 
class  MsgStartStop
 

Public Member Functions

 TestMI (DeviceAPI *deviceAPI)
 
virtual ~TestMI ()
 
virtual void destroy ()
 
virtual void init ()
 initializations to be done when all collaborating objects are created and possibly connected More...
 
virtual bool start ()
 
virtual void stop ()
 
virtual QByteArray serialize () const
 
virtual bool deserialize (const QByteArray &data)
 
virtual void setMessageQueueToGUI (MessageQueue *queue)
 
virtual const QString & getDeviceDescription () const
 
virtual int getSourceSampleRate (int index) const
 Sample rate exposed by the source at index. More...
 
virtual void setSourceSampleRate (int sampleRate, int index)
 For when the source sample rate is set externally. More...
 
virtual quint64 getSourceCenterFrequency (int index) const
 Center frequency exposed by the source at index. More...
 
virtual void setSourceCenterFrequency (qint64 centerFrequency, int index)
 
virtual int getSinkSampleRate (int index) const
 Sample rate exposed by the sink at index. More...
 
virtual void setSinkSampleRate (int sampleRate, int index)
 For when the sink sample rate is set externally. More...
 
virtual quint64 getSinkCenterFrequency (int index) const
 Center frequency exposed by the sink at index. More...
 
virtual void setSinkCenterFrequency (qint64 centerFrequency, int index)
 
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, QString &errorMessage)
 
virtual int webapiRunGet (SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
 
virtual int webapiRun (bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
 
bool isRecording (unsigned int istream) const
 
- Public Member Functions inherited from DeviceSampleMIMO
 DeviceSampleMIMO ()
 
virtual ~DeviceSampleMIMO ()
 
virtual int webapiReportGet (SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
 
MessageQueuegetInputMessageQueue ()
 
MessageQueuegetMessageQueueToGUI ()
 
unsigned int getNbSourceFifos () const
 Get the number of Tx FIFOs. More...
 
unsigned int getNbSinkFifos () const
 Get the number of Rx FIFOs. More...
 
SampleSourceFifogetSampleSourceFifo (unsigned int index)
 Get Tx FIFO at index. More...
 
SampleSinkFifogetSampleSinkFifo (unsigned int index)
 Get Rx FIFO at index. More...
 
unsigned int getNbSourceStreams () const
 Commodity function same as getNbSinkFifos (Rx or source streams) More...
 
unsigned int getNbSinkStreams () const
 Commodity function same as getNbSourceFifos (Tx or sink streams) More...
 

Private Slots

void networkManagerFinished (QNetworkReply *reply)
 

Private Member Functions

bool applySettings (const TestMISettings &settings, bool force)
 
void webapiFormatDeviceSettings (SWGSDRangel::SWGDeviceSettings &response, const TestMISettings &settings)
 
void webapiReverseSendSettings (const DeviceSettingsKeys &deviceSettingsKeys, const TestMISettings &settings, bool force)
 
void webapiReverseSendStartStop (bool start)
 

Private Attributes

DeviceAPIm_deviceAPI
 
std::vector< FileRecord * > m_fileSinks
 File sinks to record device I/Q output. More...
 
QMutex m_mutex
 
TestMISettings m_settings
 
std::vector< TestMIThread * > m_testSourceThreads
 
QString m_deviceDescription
 
bool m_running
 
const QTimer & m_masterTimer
 
QNetworkAccessManager * m_networkManager
 
QNetworkRequest m_networkRequest
 

Additional Inherited Members

- Public Types inherited from DeviceSampleMIMO
enum  fcPos_t { FC_POS_INFRA = 0, FC_POS_SUPRA, FC_POS_CENTER }
 
- Protected Slots inherited from DeviceSampleMIMO
void handleInputMessages ()
 
- Protected Attributes inherited from DeviceSampleMIMO
std::vector< SampleSourceFifom_sampleSourceFifos
 Tx FIFOs. More...
 
std::vector< SampleSinkFifom_sampleSinkFifos
 Rx FIFOs. More...
 
MessageQueue m_inputMessageQueue
 Input queue to the sink. More...
 
MessageQueuem_guiMessageQueue
 Input message queue to the GUI. More...
 

Detailed Description

Definition at line 35 of file testmi.h.

Constructor & Destructor Documentation

◆ TestMI()

TestMI::TestMI ( DeviceAPI deviceAPI)

Definition at line 45 of file testmi.cpp.

Referenced by TestMI::MsgStartStop::MsgStartStop().

45  :
46  m_deviceAPI(deviceAPI),
47  m_settings(),
49  m_running(false),
50  m_masterTimer(deviceAPI->getMasterTimer())
51 {
53  m_deviceAPI->addSourceStream(true); // Add a new source stream data set in the engine - asynchronous handling of FIFOs
54  m_deviceAPI->addSourceStream(true); // Add a new source stream data set in the engine - asynchronous handling of FIFOs
55  m_sampleSinkFifos.push_back(SampleSinkFifo(96000 * 4));
56  m_sampleSinkFifos.push_back(SampleSinkFifo(96000 * 4));
57  m_networkManager = new QNetworkAccessManager();
58  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
59 }
void setNbSourceStreams(uint32_t nbSourceStreams)
Definition: deviceapi.h:168
const QTimer & getMasterTimer() const
This is the DSPEngine master timer.
Definition: deviceapi.h:173
void networkManagerFinished(QNetworkReply *reply)
Definition: testmi.cpp:844
void addSourceStream(bool connect)
Definition: deviceapi.cpp:61
std::vector< SampleSinkFifo > m_sampleSinkFifos
Rx FIFOs.
TestMISettings m_settings
Definition: testmi.h:159
QString m_deviceDescription
Definition: testmi.h:161
QNetworkAccessManager * m_networkManager
Definition: testmi.h:164
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
bool m_running
Definition: testmi.h:162
const QTimer & m_masterTimer
Definition: testmi.h:163
+ Here is the caller graph for this function:

◆ ~TestMI()

TestMI::~TestMI ( )
virtual

Definition at line 61 of file testmi.cpp.

References m_deviceAPI, m_fileSinks, m_networkManager, m_running, networkManagerFinished(), DeviceAPI::removeAncillarySink(), DeviceAPI::removeLastSourceStream(), and stop().

Referenced by TestMI::MsgStartStop::MsgStartStop().

62 {
63  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
64  delete m_networkManager;
65 
66  if (m_running) {
67  stop();
68  }
69 
70  std::vector<FileRecord*>::iterator it = m_fileSinks.begin();
71  int istream = 0;
72 
73  for (; it != m_fileSinks.end(); ++it, istream++)
74  {
75  m_deviceAPI->removeAncillarySink(*it, istream);
76  delete *it;
77  }
78 
79  m_deviceAPI->removeLastSourceStream(); // Remove the last source stream data set in the engine
80  m_deviceAPI->removeLastSourceStream(); // Remove the last source stream data set in the engine
81 }
std::vector< FileRecord * > m_fileSinks
File sinks to record device I/Q output.
Definition: testmi.h:157
void networkManagerFinished(QNetworkReply *reply)
Definition: testmi.cpp:844
virtual void stop()
Definition: testmi.cpp:123
void removeAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Removes it.
Definition: deviceapi.cpp:100
QNetworkAccessManager * m_networkManager
Definition: testmi.h:164
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
bool m_running
Definition: testmi.h:162
void removeLastSourceStream()
Definition: deviceapi.cpp:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Function Documentation

◆ applySettings()

bool TestMI::applySettings ( const TestMISettings settings,
bool  force 
)
private

Definition at line 277 of file testmi.cpp.

References TestMIStreamSettings::AutoCorrDC, TestMIStreamSettings::AutoCorrDCAndIQ, TestMIStreamSettings::AutoCorrNone, DeviceSampleSource::calculateDeviceCenterFrequency(), DeviceSampleSource::calculateFrequencyShift(), DeviceAPI::configureCorrections(), DeviceSampleSource::FSHIFT_STD, DeviceAPI::getDeviceEngineInputMessageQueue(), m_deviceAPI, TestMISettings::m_fileRecordName, m_fileSinks, TestMISettings::m_reverseAPIAddress, TestMISettings::m_reverseAPIDeviceIndex, TestMISettings::m_reverseAPIPort, m_settings, TestMISettings::m_streams, TestMI::DeviceSettingsKeys::m_streamsSettingsKeys, m_testSourceThreads, TestMISettings::m_useReverseAPI, TestMIStreamSettings::ModulationPattern0, TestMIStreamSettings::ModulationPattern1, TestMIStreamSettings::ModulationPattern2, MessageQueue::push(), and webapiReverseSendSettings().

Referenced by handleMessage(), init(), and start().

278 {
279  DeviceSettingsKeys deviceSettingsKeys;
280 
281  qDebug() << "TestMI::applySettings: common: "
282  << " m_fileRecordName: " << settings.m_fileRecordName
283  << " m_useReverseAPI: " << settings.m_useReverseAPI
284  << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
285  << " m_reverseAPIPort: " << settings.m_reverseAPIPort
286  << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex;
287 
288  for (unsigned int istream = 0; (istream < m_settings.m_streams.size()) && (istream < settings.m_streams.size()); istream++)
289  {
290  qDebug() << "TestMI::applySettings: stream #" << istream << ": "
291  << " m_centerFrequency: " << settings.m_streams[istream].m_centerFrequency
292  << " m_frequencyShift: " << settings.m_streams[istream].m_frequencyShift
293  << " m_sampleRate: " << settings.m_streams[istream].m_sampleRate
294  << " m_log2Decim: " << settings.m_streams[istream].m_log2Decim
295  << " m_fcPos: " << settings.m_streams[istream].m_fcPos
296  << " m_amplitudeBits: " << settings.m_streams[istream].m_amplitudeBits
297  << " m_sampleSizeIndex: " << settings.m_streams[istream].m_sampleSizeIndex
298  << " m_autoCorrOptions: " << settings.m_streams[istream].m_autoCorrOptions
299  << " m_dcFactor: " << settings.m_streams[istream].m_dcFactor
300  << " m_iFactor: " << settings.m_streams[istream].m_iFactor
301  << " m_qFactor: " << settings.m_streams[istream].m_qFactor
302  << " m_phaseImbalance: " << settings.m_streams[istream].m_phaseImbalance
303  << " m_modulation: " << settings.m_streams[istream].m_modulation
304  << " m_amModulation: " << settings.m_streams[istream].m_amModulation
305  << " m_fmDeviation: " << settings.m_streams[istream].m_fmDeviation
306  << " m_modulationTone: " << settings.m_streams[istream].m_modulationTone;
307 
308  deviceSettingsKeys.m_streamsSettingsKeys.push_back(QList<QString>());
309  QList<QString>& reverseAPIKeys = deviceSettingsKeys.m_streamsSettingsKeys.back();
310 
311  if ((m_settings.m_streams[istream].m_autoCorrOptions != settings.m_streams[istream].m_autoCorrOptions) || force)
312  {
313  reverseAPIKeys.append("autoCorrOptions");
314 
315  switch(settings.m_streams[istream].m_autoCorrOptions)
316  {
318  m_deviceAPI->configureCorrections(true, false, istream);
319  break;
321  m_deviceAPI->configureCorrections(true, true, istream);
322  break;
324  default:
325  m_deviceAPI->configureCorrections(false, false, istream);
326  break;
327  }
328  }
329 
330  if ((m_settings.m_streams[istream].m_sampleRate != settings.m_streams[istream].m_sampleRate) || force)
331  {
332  reverseAPIKeys.append("sampleRate");
333 
334  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream]))
335  {
336  m_testSourceThreads[istream]->setSamplerate(settings.m_streams[istream].m_sampleRate);
337  qDebug("TestMI::applySettings: thread on stream: %u sample rate set to %d",
338  istream, settings.m_streams[istream].m_sampleRate);
339  }
340  }
341 
342  if ((m_settings.m_streams[istream].m_log2Decim != settings.m_streams[istream].m_log2Decim) || force)
343  {
344  reverseAPIKeys.append("log2Decim");
345 
346  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream]))
347  {
348  m_testSourceThreads[istream]->setLog2Decimation(settings.m_streams[istream].m_log2Decim);
349  qDebug("TestMI::applySettings: thread on stream: %u set decimation to %d",
350  istream, (1<<settings.m_streams[istream].m_log2Decim));
351  }
352  }
353 
354  if ((m_settings.m_streams[istream].m_centerFrequency != settings.m_streams[istream].m_centerFrequency)
355  || (m_settings.m_streams[istream].m_fcPos != settings.m_streams[istream].m_fcPos)
356  || (m_settings.m_streams[istream].m_frequencyShift != settings.m_streams[istream].m_frequencyShift)
357  || (m_settings.m_streams[istream].m_sampleRate != settings.m_streams[istream].m_sampleRate)
358  || (m_settings.m_streams[istream].m_log2Decim != settings.m_streams[istream].m_log2Decim) || force)
359  {
360  reverseAPIKeys.append("centerFrequency");
361  reverseAPIKeys.append("fcPos");
362  reverseAPIKeys.append("frequencyShift");
363 
364  qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency(
365  settings.m_streams[istream].m_centerFrequency,
366  0, // no transverter mode
367  settings.m_streams[istream].m_log2Decim,
368  (DeviceSampleSource::fcPos_t) settings.m_streams[istream].m_fcPos,
369  settings.m_streams[istream].m_sampleRate,
370  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD,
371  false);
372 
373  int frequencyShift = settings.m_streams[istream].m_frequencyShift;
374  quint32 devSampleRate = settings.m_streams[istream].m_sampleRate;
375 
376  if (settings.m_streams[istream].m_log2Decim != 0)
377  {
379  settings.m_streams[istream].m_log2Decim,
380  (DeviceSampleSource::fcPos_t) settings.m_streams[istream].m_fcPos,
381  settings.m_streams[istream].m_sampleRate,
383  }
384 
385  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream]))
386  {
387  m_testSourceThreads[istream]->setFcPos((int) settings.m_streams[istream].m_fcPos);
388  m_testSourceThreads[istream]->setFrequencyShift(frequencyShift);
389  qDebug() << "TestMI::applySettings:"
390  << " thread on istream: " << istream
391  << " center freq: " << settings.m_streams[istream].m_centerFrequency << " Hz"
392  << " device center freq: " << deviceCenterFrequency << " Hz"
393  << " device sample rate: " << devSampleRate << "Hz"
394  << " Actual sample rate: " << devSampleRate/(1<<m_settings.m_streams[istream].m_log2Decim) << "Hz"
395  << " f shift: " << settings.m_streams[istream].m_frequencyShift;
396  }
397  }
398 
399  if ((m_settings.m_streams[istream].m_amplitudeBits != settings.m_streams[istream].m_amplitudeBits) || force)
400  {
401  reverseAPIKeys.append("amplitudeBits");
402 
403  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
404  m_testSourceThreads[istream]->setAmplitudeBits(settings.m_streams[istream].m_amplitudeBits);
405  }
406  }
407 
408  if ((m_settings.m_streams[istream].m_dcFactor != settings.m_streams[istream].m_dcFactor) || force)
409  {
410  reverseAPIKeys.append("dcFactor");
411 
412  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
413  m_testSourceThreads[istream]->setDCFactor(settings.m_streams[istream].m_dcFactor);
414  }
415  }
416 
417  if ((m_settings.m_streams[istream].m_iFactor != settings.m_streams[istream].m_iFactor) || force)
418  {
419  reverseAPIKeys.append("iFactor");
420 
421  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
422  m_testSourceThreads[istream]->setIFactor(settings.m_streams[istream].m_iFactor);
423  }
424  }
425 
426  if ((m_settings.m_streams[istream].m_qFactor != settings.m_streams[istream].m_qFactor) || force)
427  {
428  reverseAPIKeys.append("qFactor");
429 
430  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
431  m_testSourceThreads[istream]->setQFactor(settings.m_streams[istream].m_qFactor);
432  }
433  }
434 
435  if ((m_settings.m_streams[istream].m_phaseImbalance != settings.m_streams[istream].m_phaseImbalance) || force)
436  {
437  reverseAPIKeys.append("phaseImbalance");
438 
439  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
440  m_testSourceThreads[istream]->setPhaseImbalance(settings.m_streams[istream].m_phaseImbalance);
441  }
442  }
443 
444  if ((m_settings.m_streams[istream].m_sampleSizeIndex != settings.m_streams[istream].m_sampleSizeIndex) || force)
445  {
446  reverseAPIKeys.append("sampleSizeIndex");
447 
448  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
449  m_testSourceThreads[istream]->setBitSize(settings.m_streams[istream].m_sampleSizeIndex);
450  }
451  }
452 
453  if ((m_settings.m_streams[istream].m_sampleRate != settings.m_streams[istream].m_sampleRate)
454  || (m_settings.m_streams[istream].m_centerFrequency != settings.m_streams[istream].m_centerFrequency)
455  || (m_settings.m_streams[istream].m_log2Decim != settings.m_streams[istream].m_log2Decim)
456  || (m_settings.m_streams[istream].m_fcPos != settings.m_streams[istream].m_fcPos) || force)
457  {
458  int sampleRate = settings.m_streams[istream].m_sampleRate/(1<<settings.m_streams[istream].m_log2Decim);
459  DSPSignalNotification notif(sampleRate, settings.m_streams[istream].m_centerFrequency);
460  m_fileSinks[istream]->handleMessage(notif); // forward to file sink
462  sampleRate, settings.m_streams[istream].m_centerFrequency, true, istream);
464  }
465 
466  if ((m_settings.m_streams[istream].m_modulationTone != settings.m_streams[istream].m_modulationTone) || force)
467  {
468  reverseAPIKeys.append("modulationTone");
469 
470  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
471  m_testSourceThreads[istream]->setToneFrequency(settings.m_streams[istream].m_modulationTone * 10);
472  }
473  }
474 
475  if ((m_settings.m_streams[istream].m_modulation != settings.m_streams[istream].m_modulation) || force)
476  {
477  reverseAPIKeys.append("modulation");
478 
479  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream]))
480  {
481  m_testSourceThreads[istream]->setModulation(settings.m_streams[istream].m_modulation);
482 
483  if (settings.m_streams[istream].m_modulation == TestMIStreamSettings::ModulationPattern0) {
484  m_testSourceThreads[istream]->setPattern0();
485  } else if (settings.m_streams[istream].m_modulation == TestMIStreamSettings::ModulationPattern1) {
486  m_testSourceThreads[istream]->setPattern1();
487  } else if (settings.m_streams[istream].m_modulation == TestMIStreamSettings::ModulationPattern2) {
488  m_testSourceThreads[istream]->setPattern2();
489  }
490  }
491  }
492 
493  if ((m_settings.m_streams[istream].m_amModulation != settings.m_streams[istream].m_amModulation) || force)
494  {
495  reverseAPIKeys.append("amModulation");
496 
497  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
498  m_testSourceThreads[istream]->setAMModulation(settings.m_streams[istream].m_amModulation / 100.0f);
499  }
500  }
501 
502  if ((m_settings.m_streams[istream].m_fmDeviation != settings.m_streams[istream].m_fmDeviation) || force)
503  {
504  reverseAPIKeys.append("fmDeviation");
505 
506  if ((istream < m_testSourceThreads.size()) && (m_testSourceThreads[istream])) {
507  m_testSourceThreads[istream]->setFMDeviation(settings.m_streams[istream].m_fmDeviation * 100.0f);
508  }
509  }
510  } // for each stream index
511 
512  if (settings.m_useReverseAPI)
513  {
514  qDebug("TestMI::applySettings: call webapiReverseSendSettings");
515  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
519  webapiReverseSendSettings(deviceSettingsKeys, settings, fullUpdate || force);
520  }
521 
522  m_settings = settings;
523  return true;
524 }
QString m_reverseAPIAddress
std::vector< FileRecord * > m_fileSinks
File sinks to record device I/Q output.
Definition: testmi.h:157
static qint32 calculateFrequencyShift(int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme)
static qint64 calculateDeviceCenterFrequency(quint64 centerFrequency, qint64 transverterDeltaFrequency, int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme, bool transverterMode=false)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
uint16_t m_reverseAPIPort
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
void webapiReverseSendSettings(const DeviceSettingsKeys &deviceSettingsKeys, const TestMISettings &settings, bool force)
Definition: testmi.cpp:719
TestMISettings m_settings
Definition: testmi.h:159
uint16_t m_reverseAPIDeviceIndex
std::vector< TestMIStreamSettings > m_streams
std::vector< TestMIThread * > m_testSourceThreads
Definition: testmi.h:160
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int streamIndex=0)
Configure current device engine DSP corrections (Rx)
Definition: deviceapi.cpp:355
QString m_fileRecordName
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deserialize()

bool TestMI::deserialize ( const QByteArray &  data)
virtual

Implements DeviceSampleMIMO.

Definition at line 145 of file testmi.cpp.

References TestMI::MsgConfigureTestSource::create(), TestMISettings::deserialize(), DeviceSampleMIMO::m_guiMessageQueue, DeviceSampleMIMO::m_inputMessageQueue, m_settings, MessageQueue::push(), and TestMISettings::resetToDefaults().

Referenced by TestMI::MsgStartStop::MsgStartStop().

146 {
147  bool success = true;
148 
149  if (!m_settings.deserialize(data))
150  {
152  success = false;
153  }
154 
155  MsgConfigureTestSource* message = MsgConfigureTestSource::create(m_settings, true);
156  m_inputMessageQueue.push(message);
157 
158  if (m_guiMessageQueue)
159  {
160  MsgConfigureTestSource* messageToGUI = MsgConfigureTestSource::create(m_settings, true);
161  m_guiMessageQueue->push(messageToGUI);
162  }
163 
164  return success;
165 }
void push(Message *message, bool emitSignal=true)
Push message onto queue.
static MsgConfigureTestSource * create(const TestMISettings &settings, bool force)
Definition: testmi.h:45
TestMISettings m_settings
Definition: testmi.h:159
bool deserialize(const QByteArray &data)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
MessageQueue m_inputMessageQueue
Input queue to the sink.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ destroy()

void TestMI::destroy ( )
virtual

Implements DeviceSampleMIMO.

Definition at line 83 of file testmi.cpp.

Referenced by TestMI::MsgStartStop::MsgStartStop().

84 {
85  delete this;
86 }
+ Here is the caller graph for this function:

◆ getDeviceDescription()

const QString & TestMI::getDeviceDescription ( ) const
virtual

Implements DeviceSampleMIMO.

Definition at line 167 of file testmi.cpp.

References m_deviceDescription.

Referenced by setMessageQueueToGUI().

168 {
169  return m_deviceDescription;
170 }
QString m_deviceDescription
Definition: testmi.h:161
+ Here is the caller graph for this function:

◆ getSinkCenterFrequency()

virtual quint64 TestMI::getSinkCenterFrequency ( int  index) const
inlinevirtual

Center frequency exposed by the sink at index.

Implements DeviceSampleMIMO.

Definition at line 123 of file testmi.h.

123 { return 0; (void) index; }

◆ getSinkSampleRate()

virtual int TestMI::getSinkSampleRate ( int  index) const
inlinevirtual

Sample rate exposed by the sink at index.

Implements DeviceSampleMIMO.

Definition at line 121 of file testmi.h.

121 { return 0; (void) index; }

◆ getSourceCenterFrequency()

quint64 TestMI::getSourceCenterFrequency ( int  index) const
virtual

Center frequency exposed by the source at index.

Implements DeviceSampleMIMO.

Definition at line 181 of file testmi.cpp.

References m_settings, and TestMISettings::m_streams.

Referenced by setSourceSampleRate().

182 {
183  if (index < (int) m_settings.m_streams.size()) {
184  return m_settings.m_streams[index].m_centerFrequency;
185  } else {
186  return 0;
187  }
188 }
TestMISettings m_settings
Definition: testmi.h:159
std::vector< TestMIStreamSettings > m_streams
+ Here is the caller graph for this function:

◆ getSourceSampleRate()

int TestMI::getSourceSampleRate ( int  index) const
virtual

Sample rate exposed by the source at index.

Implements DeviceSampleMIMO.

Definition at line 172 of file testmi.cpp.

References m_settings, and TestMISettings::m_streams.

Referenced by setMessageQueueToGUI().

173 {
174  if (index < (int) m_settings.m_streams.size()) {
175  return m_settings.m_streams[index].m_sampleRate/(1<<m_settings.m_streams[index].m_log2Decim);
176  } else {
177  return 0;
178  }
179 }
TestMISettings m_settings
Definition: testmi.h:159
std::vector< TestMIStreamSettings > m_streams
+ Here is the caller graph for this function:

◆ handleMessage()

bool TestMI::handleMessage ( const Message message)
virtual

Implements DeviceSampleMIMO.

Definition at line 209 of file testmi.cpp.

References applySettings(), DeviceAPI::getDeviceUID(), TestMI::MsgConfigureTestSource::getForce(), TestMI::MsgConfigureTestSource::getSettings(), TestMI::MsgFileRecord::getStartStop(), TestMI::MsgStartStop::getStartStop(), TestMI::MsgFileRecord::getStreamIndex(), DeviceAPI::initDeviceEngine(), m_deviceAPI, TestMISettings::m_fileRecordName, m_fileSinks, m_settings, TestMISettings::m_useReverseAPI, Message::match(), DeviceAPI::startDeviceEngine(), DeviceAPI::stopDeviceEngine(), and webapiReverseSendStartStop().

Referenced by setSinkCenterFrequency().

210 {
211  if (MsgConfigureTestSource::match(message))
212  {
213  MsgConfigureTestSource& conf = (MsgConfigureTestSource&) message;
214  qDebug() << "TestMI::handleMessage: MsgConfigureTestSource";
215 
216  bool success = applySettings(conf.getSettings(), conf.getForce());
217 
218  if (!success)
219  {
220  qDebug("TestMI::handleMessage: config error");
221  }
222 
223  return true;
224  }
225  else if (MsgFileRecord::match(message))
226  {
227  MsgFileRecord& conf = (MsgFileRecord&) message;
228  qDebug() << "TestMI::handleMessage: MsgFileRecord: " << conf.getStartStop();
229  int istream = conf.getStreamIndex();
230 
231  if (conf.getStartStop())
232  {
233  if (m_settings.m_fileRecordName.size() != 0) {
234  m_fileSinks[istream]->setFileName(m_settings.m_fileRecordName + "_0.sdriq");
235  } else {
236  m_fileSinks[istream]->genUniqueFileName(m_deviceAPI->getDeviceUID(), istream);
237  }
238 
239  m_fileSinks[istream]->startRecording();
240  }
241  else
242  {
243  m_fileSinks[istream]->stopRecording();
244  }
245 
246  return true;
247  }
248  else if (MsgStartStop::match(message))
249  {
250  MsgStartStop& cmd = (MsgStartStop&) message;
251  qDebug() << "TestMI::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
252 
253  if (cmd.getStartStop())
254  {
256  {
258  }
259  }
260  else
261  {
263  }
264 
266  webapiReverseSendStartStop(cmd.getStartStop());
267  }
268 
269  return true;
270  }
271  else
272  {
273  return false;
274  }
275 }
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
std::vector< FileRecord * > m_fileSinks
File sinks to record device I/Q output.
Definition: testmi.h:157
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
Definition: deviceapi.cpp:266
uint getDeviceUID() const
Return the current device engine unique ID.
Definition: deviceapi.cpp:303
bool applySettings(const TestMISettings &settings, bool force)
Definition: testmi.cpp:277
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
TestMISettings m_settings
Definition: testmi.h:159
static bool match(const Message *message)
Definition: message.cpp:45
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
void webapiReverseSendStartStop(bool start)
Definition: testmi.cpp:816
QString m_fileRecordName
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init()

void TestMI::init ( )
virtual

initializations to be done when all collaborating objects are created and possibly connected

Implements DeviceSampleMIMO.

Definition at line 88 of file testmi.cpp.

References DeviceAPI::addAncillarySink(), applySettings(), arg(), DeviceAPI::getDeviceUID(), m_deviceAPI, m_fileSinks, and m_settings.

Referenced by TestMI::MsgStartStop::MsgStartStop().

89 {
90  m_fileSinks.push_back(new FileRecord(QString("test_0_%1.sdriq").arg(m_deviceAPI->getDeviceUID())));
91  m_fileSinks.push_back(new FileRecord(QString("test_1_%1.sdriq").arg(m_deviceAPI->getDeviceUID())));
94 
96 }
std::vector< FileRecord * > m_fileSinks
File sinks to record device I/Q output.
Definition: testmi.h:157
uint getDeviceUID() const
Return the current device engine unique ID.
Definition: deviceapi.cpp:303
bool applySettings(const TestMISettings &settings, bool force)
Definition: testmi.cpp:277
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void addAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Adds a sink to receive full baseband and that is not a channel (e.g. spectrum)
Definition: deviceapi.cpp:89
TestMISettings m_settings
Definition: testmi.h:159
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isRecording()

bool TestMI::isRecording ( unsigned int  istream) const

Definition at line 862 of file testmi.cpp.

References m_fileSinks.

Referenced by setSinkCenterFrequency().

863 {
864  if (istream < m_fileSinks.size()) {
865  return m_fileSinks[istream]->isRecording();
866  } else {
867  return false;
868  }
869 }
std::vector< FileRecord * > m_fileSinks
File sinks to record device I/Q output.
Definition: testmi.h:157
+ Here is the caller graph for this function:

◆ networkManagerFinished

void TestMI::networkManagerFinished ( QNetworkReply *  reply)
privateslot

Definition at line 844 of file testmi.cpp.

Referenced by ~TestMI().

845 {
846  QNetworkReply::NetworkError replyError = reply->error();
847 
848  if (replyError)
849  {
850  qWarning() << "TestMI::networkManagerFinished:"
851  << " error(" << (int) replyError
852  << "): " << replyError
853  << ": " << reply->errorString();
854  return;
855  }
856 
857  QString answer = reply->readAll();
858  answer.chop(1); // remove last \n
859  qDebug("TestMI::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
860 }
+ Here is the caller graph for this function:

◆ serialize()

QByteArray TestMI::serialize ( ) const
virtual

Implements DeviceSampleMIMO.

Definition at line 140 of file testmi.cpp.

References m_settings, and TestMISettings::serialize().

Referenced by TestMI::MsgStartStop::MsgStartStop().

141 {
142  return m_settings.serialize();
143 }
QByteArray serialize() const
TestMISettings m_settings
Definition: testmi.h:159
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setMessageQueueToGUI()

virtual void TestMI::setMessageQueueToGUI ( MessageQueue queue)
inlinevirtual

Implements DeviceSampleMIMO.

Definition at line 113 of file testmi.h.

References getDeviceDescription(), getSourceSampleRate(), and DeviceSampleMIMO::m_guiMessageQueue.

113 { m_guiMessageQueue = queue; }
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
+ Here is the call graph for this function:

◆ setSinkCenterFrequency()

virtual void TestMI::setSinkCenterFrequency ( qint64  centerFrequency,
int  index 
)
inlinevirtual

Implements DeviceSampleMIMO.

Definition at line 124 of file testmi.h.

References handleMessage(), isRecording(), webapiRun(), webapiRunGet(), webapiSettingsGet(), and webapiSettingsPutPatch().

124 { (void) centerFrequency; (void) index; }
+ Here is the call graph for this function:

◆ setSinkSampleRate()

virtual void TestMI::setSinkSampleRate ( int  sampleRate,
int  index 
)
inlinevirtual

For when the sink sample rate is set externally.

Implements DeviceSampleMIMO.

Definition at line 122 of file testmi.h.

122 { (void) sampleRate; (void) index; }

◆ setSourceCenterFrequency()

void TestMI::setSourceCenterFrequency ( qint64  centerFrequency,
int  index 
)
virtual

Implements DeviceSampleMIMO.

Definition at line 190 of file testmi.cpp.

References TestMI::MsgConfigureTestSource::create(), DeviceSampleMIMO::m_guiMessageQueue, DeviceSampleMIMO::m_inputMessageQueue, m_settings, TestMISettings::m_streams, and MessageQueue::push().

Referenced by setSourceSampleRate().

191 {
192  TestMISettings settings = m_settings; // note: calls copy constructor
193 
194  if (index < (int) settings.m_streams.size())
195  {
196  settings.m_streams[index].m_centerFrequency = centerFrequency;
197 
198  MsgConfigureTestSource* message = MsgConfigureTestSource::create(settings, false);
199  m_inputMessageQueue.push(message);
200 
201  if (m_guiMessageQueue)
202  {
203  MsgConfigureTestSource* messageToGUI = MsgConfigureTestSource::create(settings, false);
204  m_guiMessageQueue->push(messageToGUI);
205  }
206  }
207 }
void push(Message *message, bool emitSignal=true)
Push message onto queue.
static MsgConfigureTestSource * create(const TestMISettings &settings, bool force)
Definition: testmi.h:45
TestMISettings m_settings
Definition: testmi.h:159
std::vector< TestMIStreamSettings > m_streams
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
MessageQueue m_inputMessageQueue
Input queue to the sink.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setSourceSampleRate()

virtual void TestMI::setSourceSampleRate ( int  sampleRate,
int  index 
)
inlinevirtual

For when the source sample rate is set externally.

Implements DeviceSampleMIMO.

Definition at line 117 of file testmi.h.

References getSourceCenterFrequency(), and setSourceCenterFrequency().

117 { (void) sampleRate; (void) index; }
+ Here is the call graph for this function:

◆ start()

bool TestMI::start ( )
virtual

Implements DeviceSampleMIMO.

Definition at line 98 of file testmi.cpp.

References applySettings(), m_mutex, m_running, DeviceSampleMIMO::m_sampleSinkFifos, m_settings, TestMISettings::m_streams, m_testSourceThreads, and stop().

Referenced by TestMI::MsgStartStop::MsgStartStop().

99 {
100  qDebug("TestMI::start");
101  QMutexLocker mutexLocker(&m_mutex);
102 
103  if (m_running) {
104  stop();
105  }
106 
107  m_testSourceThreads.push_back(new TestMIThread(&m_sampleSinkFifos[0], 0));
108  m_testSourceThreads.back()->setSamplerate(m_settings.m_streams[0].m_sampleRate);
109  m_testSourceThreads.back()->startStop(true);
110 
111  m_testSourceThreads.push_back(new TestMIThread(&m_sampleSinkFifos[1], 1));
112  m_testSourceThreads.back()->setSamplerate(m_settings.m_streams[1].m_sampleRate);
113  m_testSourceThreads.back()->startStop(true);
114 
115  mutexLocker.unlock();
116 
117  applySettings(m_settings, true);
118  m_running = true;
119 
120  return true;
121 }
QMutex m_mutex
Definition: testmi.h:158
bool applySettings(const TestMISettings &settings, bool force)
Definition: testmi.cpp:277
std::vector< SampleSinkFifo > m_sampleSinkFifos
Rx FIFOs.
TestMISettings m_settings
Definition: testmi.h:159
virtual void stop()
Definition: testmi.cpp:123
std::vector< TestMIStreamSettings > m_streams
std::vector< TestMIThread * > m_testSourceThreads
Definition: testmi.h:160
bool m_running
Definition: testmi.h:162
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ stop()

void TestMI::stop ( )
virtual

Implements DeviceSampleMIMO.

Definition at line 123 of file testmi.cpp.

References m_mutex, m_running, and m_testSourceThreads.

Referenced by TestMI::MsgStartStop::MsgStartStop(), start(), and ~TestMI().

124 {
125  qDebug("TestMI::stop");
126  QMutexLocker mutexLocker(&m_mutex);
127 
128  std::vector<TestMIThread*>::iterator it = m_testSourceThreads.begin();
129 
130  for (; it != m_testSourceThreads.end(); ++it)
131  {
132  (*it)->startStop(false);
133  (*it)->deleteLater();
134  }
135 
136  m_testSourceThreads.clear();
137  m_running = false;
138 }
QMutex m_mutex
Definition: testmi.h:158
std::vector< TestMIThread * > m_testSourceThreads
Definition: testmi.h:160
bool m_running
Definition: testmi.h:162
+ Here is the caller graph for this function:

◆ webapiFormatDeviceSettings()

void TestMI::webapiFormatDeviceSettings ( SWGSDRangel::SWGDeviceSettings response,
const TestMISettings settings 
)
private

Definition at line 672 of file testmi.cpp.

References SWGSDRangel::SWGTestMISettings::getFileRecordName(), SWGSDRangel::SWGTestMISettings::getReverseApiAddress(), SWGSDRangel::SWGTestMISettings::getStreams(), SWGSDRangel::SWGDeviceSettings::getTestMiSettings(), TestMISettings::m_fileRecordName, TestMISettings::m_reverseAPIAddress, TestMISettings::m_reverseAPIDeviceIndex, TestMISettings::m_reverseAPIPort, TestMISettings::m_streams, TestMISettings::m_useReverseAPI, SWGSDRangel::SWGTestMISettings::setFileRecordName(), SWGSDRangel::SWGTestMISettings::setReverseApiAddress(), SWGSDRangel::SWGTestMISettings::setReverseApiDeviceIndex(), SWGSDRangel::SWGTestMISettings::setReverseApiPort(), and SWGSDRangel::SWGTestMISettings::setUseReverseApi().

Referenced by webapiSettingsGet(), and webapiSettingsPutPatch().

673 {
674  std::vector<TestMIStreamSettings>::const_iterator it = settings.m_streams.begin();
675  int istream = 0;
676 
677  for (; it != settings.m_streams.end(); ++it, istream++)
678  {
679  QList<SWGSDRangel::SWGTestMiStreamSettings*> *streams = response.getTestMiSettings()->getStreams();
680  streams->append(new SWGSDRangel::SWGTestMiStreamSettings);
681  streams->back()->init();
682  streams->back()->setStreamIndex(istream);
683  streams->back()->setCenterFrequency(it->m_centerFrequency);
684  streams->back()->setFrequencyShift(it->m_frequencyShift);
685  streams->back()->setSampleRate(it->m_sampleRate);
686  streams->back()->setLog2Decim(it->m_log2Decim);
687  streams->back()->setFcPos((int) it->m_fcPos);
688  streams->back()->setSampleSizeIndex((int) it->m_sampleSizeIndex);
689  streams->back()->setAmplitudeBits(it->m_amplitudeBits);
690  streams->back()->setAutoCorrOptions((int) it->m_autoCorrOptions);
691  streams->back()->setModulation((int) it->m_modulation);
692  streams->back()->setModulationTone(it->m_modulationTone);
693  streams->back()->setAmModulation(it->m_amModulation);
694  streams->back()->setFmDeviation(it->m_fmDeviation);
695  streams->back()->setDcFactor(it->m_dcFactor);
696  streams->back()->setIFactor(it->m_iFactor);
697  streams->back()->setQFactor(it->m_qFactor);
698  streams->back()->setPhaseImbalance(it->m_phaseImbalance);
699  }
700 
701  if (response.getTestMiSettings()->getFileRecordName()) {
702  *response.getTestMiSettings()->getFileRecordName() = settings.m_fileRecordName;
703  } else {
704  response.getTestMiSettings()->setFileRecordName(new QString(settings.m_fileRecordName));
705  }
706 
707  response.getTestMiSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
708 
709  if (response.getTestMiSettings()->getReverseApiAddress()) {
711  } else {
712  response.getTestMiSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
713  }
714 
717 }
QString m_reverseAPIAddress
uint16_t m_reverseAPIPort
void setUseReverseApi(qint32 use_reverse_api)
SWGTestMISettings * getTestMiSettings()
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
uint16_t m_reverseAPIDeviceIndex
std::vector< TestMIStreamSettings > m_streams
QList< SWGTestMiStreamSettings * > * getStreams()
void setReverseApiAddress(QString *reverse_api_address)
void setFileRecordName(QString *file_record_name)
void setReverseApiPort(qint32 reverse_api_port)
QString m_fileRecordName
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReverseSendSettings()

void TestMI::webapiReverseSendSettings ( const DeviceSettingsKeys deviceSettingsKeys,
const TestMISettings settings,
bool  force 
)
private

Definition at line 719 of file testmi.cpp.

References SWGSDRangel::SWGDeviceSettings::asJson(), DeviceAPI::getDeviceSetIndex(), SWGSDRangel::SWGTestMISettings::getStreams(), SWGSDRangel::SWGDeviceSettings::getTestMiSettings(), TestMI::DeviceSettingsKeys::m_commonSettingsKeys, m_deviceAPI, TestMISettings::m_fileRecordName, m_networkManager, m_networkRequest, TestMISettings::m_reverseAPIAddress, TestMISettings::m_reverseAPIDeviceIndex, TestMISettings::m_reverseAPIPort, TestMISettings::m_streams, TestMI::DeviceSettingsKeys::m_streamsSettingsKeys, SWGSDRangel::SWGDeviceSettings::setDeviceHwType(), SWGSDRangel::SWGDeviceSettings::setDirection(), SWGSDRangel::SWGTestMISettings::setFileRecordName(), SWGSDRangel::SWGDeviceSettings::setOriginatorIndex(), and SWGSDRangel::SWGDeviceSettings::setTestMiSettings().

Referenced by applySettings().

720 {
722  swgDeviceSettings->setDirection(0); // single Rx
723  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
724  swgDeviceSettings->setDeviceHwType(new QString("TestSource"));
725  swgDeviceSettings->setTestMiSettings(new SWGSDRangel::SWGTestMISettings());
726  SWGSDRangel::SWGTestMISettings *swgTestMISettings = swgDeviceSettings->getTestMiSettings();
727 
728  // transfer data that has been modified. When force is on transfer all data except reverse API data
729 
730  QList<QList<QString>>::const_iterator it = deviceSettingsKeys.m_streamsSettingsKeys.begin();
731  int istream = 0;
732 
733  for (; it != deviceSettingsKeys.m_streamsSettingsKeys.end(); ++it, istream++)
734  {
735  if ((it->size() > 0) || force)
736  {
737  QList<SWGSDRangel::SWGTestMiStreamSettings*> *streams = swgTestMISettings->getStreams();
738  streams->append(new SWGSDRangel::SWGTestMiStreamSettings);
739  streams->back()->init();
740  streams->back()->setStreamIndex(istream);
741  const QList<QString>& streamSettingsKeys = *it;
742 
743  if (streamSettingsKeys.contains("centerFrequency") || force) {
744  streams->back()->setCenterFrequency(settings.m_streams[istream].m_centerFrequency);
745  }
746  if (streamSettingsKeys.contains("frequencyShift") || force) {
747  streams->back()->setFrequencyShift(settings.m_streams[istream].m_frequencyShift);
748  }
749  if (streamSettingsKeys.contains("sampleRate") || force) {
750  streams->back()->setSampleRate(settings.m_streams[istream].m_sampleRate);
751  }
752  if (streamSettingsKeys.contains("log2Decim") || force) {
753  streams->back()->setLog2Decim(settings.m_streams[istream].m_log2Decim);
754  }
755  if (streamSettingsKeys.contains("fcPos") || force) {
756  streams->back()->setFcPos((int) settings.m_streams[istream].m_fcPos);
757  }
758  if (streamSettingsKeys.contains("sampleSizeIndex") || force) {
759  streams->back()->setSampleSizeIndex(settings.m_streams[istream].m_sampleSizeIndex);
760  }
761  if (streamSettingsKeys.contains("amplitudeBits") || force) {
762  streams->back()->setAmplitudeBits(settings.m_streams[istream].m_amplitudeBits);
763  }
764  if (streamSettingsKeys.contains("autoCorrOptions") || force) {
765  streams->back()->setAutoCorrOptions((int) settings.m_streams[istream].m_sampleSizeIndex);
766  }
767  if (streamSettingsKeys.contains("modulation") || force) {
768  streams->back()->setModulation((int) settings.m_streams[istream].m_modulation);
769  }
770  if (streamSettingsKeys.contains("modulationTone")) {
771  streams->back()->setModulationTone(settings.m_streams[istream].m_modulationTone);
772  }
773  if (streamSettingsKeys.contains("amModulation") || force) {
774  streams->back()->setAmModulation(settings.m_streams[istream].m_amModulation);
775  };
776  if (streamSettingsKeys.contains("fmDeviation") || force) {
777  streams->back()->setFmDeviation(settings.m_streams[istream].m_fmDeviation);
778  };
779  if (streamSettingsKeys.contains("dcFactor") || force) {
780  streams->back()->setDcFactor(settings.m_streams[istream].m_dcFactor);
781  };
782  if (streamSettingsKeys.contains("iFactor") || force) {
783  streams->back()->setIFactor(settings.m_streams[istream].m_iFactor);
784  };
785  if (streamSettingsKeys.contains("qFactor") || force) {
786  streams->back()->setQFactor(settings.m_streams[istream].m_qFactor);
787  };
788  if (streamSettingsKeys.contains("phaseImbalance") || force) {
789  streams->back()->setPhaseImbalance(settings.m_streams[istream].m_phaseImbalance);
790  };
791  }
792  }
793 
794  if (deviceSettingsKeys.m_commonSettingsKeys.contains("fileRecordName") || force) {
795  swgTestMISettings->setFileRecordName(new QString(settings.m_fileRecordName));
796  }
797 
798  QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
799  .arg(settings.m_reverseAPIAddress)
800  .arg(settings.m_reverseAPIPort)
801  .arg(settings.m_reverseAPIDeviceIndex);
802  m_networkRequest.setUrl(QUrl(channelSettingsURL));
803  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
804 
805  QBuffer *buffer=new QBuffer();
806  buffer->open((QBuffer::ReadWrite));
807  buffer->write(swgDeviceSettings->asJson().toUtf8());
808  buffer->seek(0);
809 
810  // Always use PATCH to avoid passing reverse API settings
811  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
812 
813  delete swgDeviceSettings;
814 }
QString m_reverseAPIAddress
uint16_t m_reverseAPIPort
virtual QString asJson() override
SWGTestMISettings * getTestMiSettings()
void setOriginatorIndex(qint32 originator_index)
int getDeviceSetIndex() const
Definition: deviceapi.h:131
uint16_t m_reverseAPIDeviceIndex
std::vector< TestMIStreamSettings > m_streams
QList< SWGTestMiStreamSettings * > * getStreams()
void setTestMiSettings(SWGTestMISettings *test_mi_settings)
void setFileRecordName(QString *file_record_name)
QNetworkAccessManager * m_networkManager
Definition: testmi.h:164
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
void setDirection(qint32 direction)
QString m_fileRecordName
QNetworkRequest m_networkRequest
Definition: testmi.h:165
void setDeviceHwType(QString *device_hw_type)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReverseSendStartStop()

void TestMI::webapiReverseSendStartStop ( bool  start)
private

Definition at line 816 of file testmi.cpp.

References SWGSDRangel::SWGDeviceSettings::asJson(), DeviceAPI::getDeviceSetIndex(), m_deviceAPI, m_networkManager, m_networkRequest, TestMISettings::m_reverseAPIAddress, TestMISettings::m_reverseAPIDeviceIndex, TestMISettings::m_reverseAPIPort, m_settings, SWGSDRangel::SWGDeviceSettings::setDeviceHwType(), SWGSDRangel::SWGDeviceSettings::setDirection(), and SWGSDRangel::SWGDeviceSettings::setOriginatorIndex().

Referenced by handleMessage().

817 {
819  swgDeviceSettings->setDirection(0); // single Rx
820  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
821  swgDeviceSettings->setDeviceHwType(new QString("TestSource"));
822 
823  QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
827  m_networkRequest.setUrl(QUrl(channelSettingsURL));
828  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
829 
830  QBuffer *buffer=new QBuffer();
831  buffer->open((QBuffer::ReadWrite));
832  buffer->write(swgDeviceSettings->asJson().toUtf8());
833  buffer->seek(0);
834 
835  if (start) {
836  m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
837  } else {
838  m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
839  }
840 
841  delete swgDeviceSettings;
842 }
QString m_reverseAPIAddress
uint16_t m_reverseAPIPort
virtual QString asJson() override
void setOriginatorIndex(qint32 originator_index)
int getDeviceSetIndex() const
Definition: deviceapi.h:131
TestMISettings m_settings
Definition: testmi.h:159
uint16_t m_reverseAPIDeviceIndex
QNetworkAccessManager * m_networkManager
Definition: testmi.h:164
virtual bool start()
Definition: testmi.cpp:98
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
void setDirection(qint32 direction)
QNetworkRequest m_networkRequest
Definition: testmi.h:165
void setDeviceHwType(QString *device_hw_type)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiRun()

int TestMI::webapiRun ( bool  run,
SWGSDRangel::SWGDeviceState response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleMIMO.

Definition at line 535 of file testmi.cpp.

References TestMI::MsgStartStop::create(), DeviceAPI::getDeviceEngineStateStr(), SWGSDRangel::SWGDeviceState::getState(), m_deviceAPI, DeviceSampleMIMO::m_guiMessageQueue, DeviceSampleMIMO::m_inputMessageQueue, and MessageQueue::push().

Referenced by setSinkCenterFrequency().

539 {
540  (void) errorMessage;
542  MsgStartStop *message = MsgStartStop::create(run);
543  m_inputMessageQueue.push(message);
544 
545  if (m_guiMessageQueue) // forward to GUI if any
546  {
547  MsgStartStop *msgToGUI = MsgStartStop::create(run);
548  m_guiMessageQueue->push(msgToGUI);
549  }
550 
551  return 200;
552 }
void push(Message *message, bool emitSignal=true)
Push message onto queue.
static MsgStartStop * create(bool startStop)
Definition: testmi.h:89
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
MessageQueue m_inputMessageQueue
Input queue to the sink.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiRunGet()

int TestMI::webapiRunGet ( SWGSDRangel::SWGDeviceState response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleMIMO.

Definition at line 526 of file testmi.cpp.

References DeviceAPI::getDeviceEngineStateStr(), SWGSDRangel::SWGDeviceState::getState(), and m_deviceAPI.

Referenced by setSinkCenterFrequency().

529 {
530  (void) errorMessage;
532  return 200;
533 }
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
DeviceAPI * m_deviceAPI
Definition: testmi.h:156
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiSettingsGet()

int TestMI::webapiSettingsGet ( SWGSDRangel::SWGDeviceSettings response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleMIMO.

Definition at line 554 of file testmi.cpp.

References SWGSDRangel::SWGDeviceSettings::getTestMiSettings(), SWGSDRangel::SWGTestMISettings::init(), m_settings, SWGSDRangel::SWGDeviceSettings::setTestMiSettings(), and webapiFormatDeviceSettings().

Referenced by setSinkCenterFrequency().

557 {
558  (void) errorMessage;
560  response.getTestMiSettings()->init();
562  return 200;
563 }
SWGTestMISettings * getTestMiSettings()
TestMISettings m_settings
Definition: testmi.h:159
void setTestMiSettings(SWGTestMISettings *test_mi_settings)
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const TestMISettings &settings)
Definition: testmi.cpp:672
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiSettingsPutPatch()

int TestMI::webapiSettingsPutPatch ( bool  force,
const QStringList &  deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleMIMO.

Definition at line 565 of file testmi.cpp.

References arg(), TestMIStreamSettings::AutoCorrLast, TestMI::MsgConfigureTestSource::create(), SWGSDRangel::SWGTestMISettings::getFileRecordName(), SWGSDRangel::SWGTestMISettings::getReverseApiAddress(), SWGSDRangel::SWGTestMISettings::getReverseApiDeviceIndex(), SWGSDRangel::SWGTestMISettings::getReverseApiPort(), SWGSDRangel::SWGTestMISettings::getStreams(), SWGSDRangel::SWGDeviceSettings::getTestMiSettings(), SWGSDRangel::SWGTestMISettings::getUseReverseApi(), TestMISettings::m_fileRecordName, DeviceSampleMIMO::m_guiMessageQueue, DeviceSampleMIMO::m_inputMessageQueue, TestMISettings::m_reverseAPIAddress, TestMISettings::m_reverseAPIDeviceIndex, TestMISettings::m_reverseAPIPort, m_settings, TestMISettings::m_streams, TestMISettings::m_useReverseAPI, TestMIStreamSettings::ModulationLast, MessageQueue::push(), and webapiFormatDeviceSettings().

Referenced by setSinkCenterFrequency().

570 {
571  (void) errorMessage;
572  TestMISettings settings = m_settings;
573 
574  if (deviceSettingsKeys.contains("streams"))
575  {
576  QList<SWGSDRangel::SWGTestMiStreamSettings*> *streamsSettings = response.getTestMiSettings()->getStreams();
577  QList<SWGSDRangel::SWGTestMiStreamSettings*>::const_iterator it = streamsSettings->begin();
578 
579  for (; it != streamsSettings->end(); ++it)
580  {
581  int istream = (*it)->getStreamIndex();
582 
583  if (deviceSettingsKeys.contains(tr("streams[%1].centerFrequency").arg(istream))) {
584  settings.m_streams[istream].m_centerFrequency = (*it)->getCenterFrequency();
585  }
586  if (deviceSettingsKeys.contains(tr("streams[%1].frequencyShift").arg(istream))) {
587  settings.m_streams[istream].m_frequencyShift = (*it)->getFrequencyShift();
588  }
589  if (deviceSettingsKeys.contains(tr("streams[%1].sampleRate").arg(istream))) {
590  settings.m_streams[istream].m_sampleRate = (*it)->getSampleRate();
591  }
592  if (deviceSettingsKeys.contains(tr("streams[%1].log2Decim").arg(istream))) {
593  settings.m_streams[istream].m_log2Decim = (*it)->getLog2Decim();
594  }
595  if (deviceSettingsKeys.contains(tr("streams[%1].fcPos").arg(istream))) {
596  int fcPos = (*it)->getFcPos();
597  fcPos = fcPos < 0 ? 0 : fcPos > 2 ? 2 : fcPos;
598  settings.m_streams[istream].m_fcPos = (TestMIStreamSettings::fcPos_t) fcPos;
599  }
600  if (deviceSettingsKeys.contains(tr("streams[%1].sampleSizeIndex").arg(istream))) {
601  int sampleSizeIndex = (*it)->getSampleSizeIndex();
602  sampleSizeIndex = sampleSizeIndex < 0 ? 0 : sampleSizeIndex > 1 ? 2 : sampleSizeIndex;
603  settings.m_streams[istream].m_sampleSizeIndex = sampleSizeIndex;
604  }
605  if (deviceSettingsKeys.contains(tr("streams[%1].amplitudeBits").arg(istream))) {
606  settings.m_streams[istream].m_amplitudeBits = (*it)->getAmplitudeBits();
607  }
608  if (deviceSettingsKeys.contains(tr("streams[%1].autoCorrOptions").arg(istream))) {
609  int autoCorrOptions = (*it)->getAutoCorrOptions();
610  autoCorrOptions = autoCorrOptions < 0 ? 0 : autoCorrOptions >= TestMIStreamSettings::AutoCorrLast ? TestMIStreamSettings::AutoCorrLast-1 : autoCorrOptions;
611  settings.m_streams[istream].m_sampleSizeIndex = (TestMIStreamSettings::AutoCorrOptions) autoCorrOptions;
612  }
613  if (deviceSettingsKeys.contains(tr("streams[%1].modulation").arg(istream))) {
614  int modulation = (*it)->getModulation();
615  modulation = modulation < 0 ? 0 : modulation >= TestMIStreamSettings::ModulationLast ? TestMIStreamSettings::ModulationLast-1 : modulation;
616  settings.m_streams[istream].m_modulation = (TestMIStreamSettings::Modulation) modulation;
617  }
618  if (deviceSettingsKeys.contains(tr("streams[%1].modulationTone").arg(istream))) {
619  settings.m_streams[istream].m_modulationTone = (*it)->getModulationTone();
620  }
621  if (deviceSettingsKeys.contains(tr("streams[%1].amModulation").arg(istream))) {
622  settings.m_streams[istream].m_amModulation = (*it)->getAmModulation();
623  };
624  if (deviceSettingsKeys.contains(tr("streams[%1].fmDeviation").arg(istream))) {
625  settings.m_streams[istream].m_fmDeviation = (*it)->getFmDeviation();
626  };
627  if (deviceSettingsKeys.contains(tr("streams[%1].dcFactor").arg(istream))) {
628  settings.m_streams[istream].m_dcFactor = (*it)->getDcFactor();
629  };
630  if (deviceSettingsKeys.contains(tr("streams[%1].iFactor").arg(istream))) {
631  settings.m_streams[istream].m_iFactor = (*it)->getIFactor();
632  };
633  if (deviceSettingsKeys.contains(tr("streams[%1].qFactor").arg(istream))) {
634  settings.m_streams[istream].m_qFactor = (*it)->getQFactor();
635  };
636  if (deviceSettingsKeys.contains(tr("streams[%1].phaseImbalance").arg(istream))) {
637  settings.m_streams[istream].m_phaseImbalance = (*it)->getPhaseImbalance();
638  };
639  }
640 
641  }
642 
643  if (deviceSettingsKeys.contains("fileRecordName")) {
644  settings.m_fileRecordName = *response.getTestMiSettings()->getFileRecordName();
645  }
646  if (deviceSettingsKeys.contains("useReverseAPI")) {
647  settings.m_useReverseAPI = response.getTestMiSettings()->getUseReverseApi() != 0;
648  }
649  if (deviceSettingsKeys.contains("reverseAPIAddress")) {
651  }
652  if (deviceSettingsKeys.contains("reverseAPIPort")) {
653  settings.m_reverseAPIPort = response.getTestMiSettings()->getReverseApiPort();
654  }
655  if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
657  }
658 
659  MsgConfigureTestSource *msg = MsgConfigureTestSource::create(settings, force);
661 
662  if (m_guiMessageQueue) // forward to GUI if any
663  {
664  MsgConfigureTestSource *msgToGUI = MsgConfigureTestSource::create(settings, force);
665  m_guiMessageQueue->push(msgToGUI);
666  }
667 
668  webapiFormatDeviceSettings(response, settings);
669  return 200;
670 }
QString m_reverseAPIAddress
void push(Message *message, bool emitSignal=true)
Push message onto queue.
uint16_t m_reverseAPIPort
SWGTestMISettings * getTestMiSettings()
static MsgConfigureTestSource * create(const TestMISettings &settings, bool force)
Definition: testmi.h:45
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
TestMISettings m_settings
Definition: testmi.h:159
uint16_t m_reverseAPIDeviceIndex
std::vector< TestMIStreamSettings > m_streams
QList< SWGTestMiStreamSettings * > * getStreams()
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const TestMISettings &settings)
Definition: testmi.cpp:672
MessageQueue m_inputMessageQueue
Input queue to the sink.
QString m_fileRecordName
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ m_deviceAPI

DeviceAPI* TestMI::m_deviceAPI
private

◆ m_deviceDescription

QString TestMI::m_deviceDescription
private

Definition at line 161 of file testmi.h.

Referenced by getDeviceDescription().

◆ m_fileSinks

std::vector<FileRecord *> TestMI::m_fileSinks
private

File sinks to record device I/Q output.

Definition at line 157 of file testmi.h.

Referenced by applySettings(), handleMessage(), init(), isRecording(), and ~TestMI().

◆ m_masterTimer

const QTimer& TestMI::m_masterTimer
private

Definition at line 163 of file testmi.h.

◆ m_mutex

QMutex TestMI::m_mutex
private

Definition at line 158 of file testmi.h.

Referenced by start(), and stop().

◆ m_networkManager

QNetworkAccessManager* TestMI::m_networkManager
private

Definition at line 164 of file testmi.h.

Referenced by webapiReverseSendSettings(), webapiReverseSendStartStop(), and ~TestMI().

◆ m_networkRequest

QNetworkRequest TestMI::m_networkRequest
private

Definition at line 165 of file testmi.h.

Referenced by webapiReverseSendSettings(), and webapiReverseSendStartStop().

◆ m_running

bool TestMI::m_running
private

Definition at line 162 of file testmi.h.

Referenced by start(), stop(), and ~TestMI().

◆ m_settings

TestMISettings TestMI::m_settings
private

◆ m_testSourceThreads

std::vector<TestMIThread*> TestMI::m_testSourceThreads
private

Definition at line 160 of file testmi.h.

Referenced by applySettings(), start(), and stop().


The documentation for this class was generated from the following files: