22 #include <QNetworkReply> 23 #include <QNetworkAccessManager> 46 m_deviceAPI(deviceAPI),
48 m_deviceDescription(),
50 m_masterTimer(deviceAPI->getMasterTimer())
52 m_deviceAPI->setNbSourceStreams(2);
53 m_deviceAPI->addSourceStream(
true);
54 m_deviceAPI->addSourceStream(
true);
57 m_networkManager =
new QNetworkAccessManager();
58 connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(networkManagerFinished(QNetworkReply*)));
70 std::vector<FileRecord*>::iterator it =
m_fileSinks.begin();
100 qDebug(
"TestMI::start");
101 QMutexLocker mutexLocker(&
m_mutex);
115 mutexLocker.unlock();
125 qDebug(
"TestMI::stop");
126 QMutexLocker mutexLocker(&
m_mutex);
132 (*it)->startStop(
false);
133 (*it)->deleteLater();
194 if (index < (
int) settings.
m_streams.size())
196 settings.
m_streams[index].m_centerFrequency = centerFrequency;
214 qDebug() <<
"TestMI::handleMessage: MsgConfigureTestSource";
220 qDebug(
"TestMI::handleMessage: config error");
228 qDebug() <<
"TestMI::handleMessage: MsgFileRecord: " << conf.
getStartStop();
251 qDebug() <<
"TestMI::handleMessage: MsgStartStop: " << (cmd.
getStartStop() ?
"start" :
"stop");
281 qDebug() <<
"TestMI::applySettings: common: " 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;
313 reverseAPIKeys.append(
"autoCorrOptions");
315 switch(settings.
m_streams[istream].m_autoCorrOptions)
332 reverseAPIKeys.append(
"sampleRate");
337 qDebug(
"TestMI::applySettings: thread on stream: %u sample rate set to %d",
338 istream, settings.
m_streams[istream].m_sampleRate);
344 reverseAPIKeys.append(
"log2Decim");
349 qDebug(
"TestMI::applySettings: thread on stream: %u set decimation to %d",
350 istream, (1<<settings.
m_streams[istream].m_log2Decim));
360 reverseAPIKeys.append(
"centerFrequency");
361 reverseAPIKeys.append(
"fcPos");
362 reverseAPIKeys.append(
"frequencyShift");
365 settings.
m_streams[istream].m_centerFrequency,
369 settings.
m_streams[istream].m_sampleRate,
370 DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD,
373 int frequencyShift = settings.
m_streams[istream].m_frequencyShift;
374 quint32 devSampleRate = settings.
m_streams[istream].m_sampleRate;
376 if (settings.
m_streams[istream].m_log2Decim != 0)
381 settings.
m_streams[istream].m_sampleRate,
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;
401 reverseAPIKeys.append(
"amplitudeBits");
410 reverseAPIKeys.append(
"dcFactor");
419 reverseAPIKeys.append(
"iFactor");
428 reverseAPIKeys.append(
"qFactor");
437 reverseAPIKeys.append(
"phaseImbalance");
446 reverseAPIKeys.append(
"sampleSizeIndex");
458 int sampleRate = settings.
m_streams[istream].m_sampleRate/(1<<settings.
m_streams[istream].m_log2Decim);
462 sampleRate, settings.
m_streams[istream].m_centerFrequency,
true, istream);
468 reverseAPIKeys.append(
"modulationTone");
477 reverseAPIKeys.append(
"modulation");
495 reverseAPIKeys.append(
"amModulation");
504 reverseAPIKeys.append(
"fmDeviation");
514 qDebug(
"TestMI::applySettings: call webapiReverseSendSettings");
528 QString& errorMessage)
538 QString& errorMessage)
556 QString& errorMessage)
567 const QStringList& deviceSettingsKeys,
569 QString& errorMessage)
574 if (deviceSettingsKeys.contains(
"streams"))
577 QList<SWGSDRangel::SWGTestMiStreamSettings*>::const_iterator it = streamsSettings->begin();
579 for (; it != streamsSettings->end(); ++it)
581 int istream = (*it)->getStreamIndex();
583 if (deviceSettingsKeys.contains(tr(
"streams[%1].centerFrequency").
arg(istream))) {
584 settings.
m_streams[istream].m_centerFrequency = (*it)->getCenterFrequency();
586 if (deviceSettingsKeys.contains(tr(
"streams[%1].frequencyShift").
arg(istream))) {
587 settings.
m_streams[istream].m_frequencyShift = (*it)->getFrequencyShift();
589 if (deviceSettingsKeys.contains(tr(
"streams[%1].sampleRate").
arg(istream))) {
590 settings.
m_streams[istream].m_sampleRate = (*it)->getSampleRate();
592 if (deviceSettingsKeys.contains(tr(
"streams[%1].log2Decim").
arg(istream))) {
593 settings.
m_streams[istream].m_log2Decim = (*it)->getLog2Decim();
595 if (deviceSettingsKeys.contains(tr(
"streams[%1].fcPos").
arg(istream))) {
596 int fcPos = (*it)->getFcPos();
597 fcPos = fcPos < 0 ? 0 : fcPos > 2 ? 2 : fcPos;
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;
605 if (deviceSettingsKeys.contains(tr(
"streams[%1].amplitudeBits").
arg(istream))) {
606 settings.
m_streams[istream].m_amplitudeBits = (*it)->getAmplitudeBits();
608 if (deviceSettingsKeys.contains(tr(
"streams[%1].autoCorrOptions").
arg(istream))) {
609 int autoCorrOptions = (*it)->getAutoCorrOptions();
613 if (deviceSettingsKeys.contains(tr(
"streams[%1].modulation").
arg(istream))) {
614 int modulation = (*it)->getModulation();
618 if (deviceSettingsKeys.contains(tr(
"streams[%1].modulationTone").
arg(istream))) {
619 settings.
m_streams[istream].m_modulationTone = (*it)->getModulationTone();
621 if (deviceSettingsKeys.contains(tr(
"streams[%1].amModulation").
arg(istream))) {
622 settings.
m_streams[istream].m_amModulation = (*it)->getAmModulation();
624 if (deviceSettingsKeys.contains(tr(
"streams[%1].fmDeviation").
arg(istream))) {
625 settings.
m_streams[istream].m_fmDeviation = (*it)->getFmDeviation();
627 if (deviceSettingsKeys.contains(tr(
"streams[%1].dcFactor").
arg(istream))) {
628 settings.
m_streams[istream].m_dcFactor = (*it)->getDcFactor();
630 if (deviceSettingsKeys.contains(tr(
"streams[%1].iFactor").
arg(istream))) {
631 settings.
m_streams[istream].m_iFactor = (*it)->getIFactor();
633 if (deviceSettingsKeys.contains(tr(
"streams[%1].qFactor").
arg(istream))) {
634 settings.
m_streams[istream].m_qFactor = (*it)->getQFactor();
636 if (deviceSettingsKeys.contains(tr(
"streams[%1].phaseImbalance").
arg(istream))) {
637 settings.
m_streams[istream].m_phaseImbalance = (*it)->getPhaseImbalance();
643 if (deviceSettingsKeys.contains(
"fileRecordName")) {
646 if (deviceSettingsKeys.contains(
"useReverseAPI")) {
649 if (deviceSettingsKeys.contains(
"reverseAPIAddress")) {
652 if (deviceSettingsKeys.contains(
"reverseAPIPort")) {
655 if (deviceSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
674 std::vector<TestMIStreamSettings>::const_iterator it = settings.
m_streams.begin();
677 for (; it != settings.
m_streams.end(); ++it, istream++)
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);
735 if ((it->size() > 0) || force)
737 QList<SWGSDRangel::SWGTestMiStreamSettings*> *streams = swgTestMISettings->
getStreams();
739 streams->back()->init();
740 streams->back()->setStreamIndex(istream);
741 const QList<QString>& streamSettingsKeys = *it;
743 if (streamSettingsKeys.contains(
"centerFrequency") || force) {
744 streams->back()->setCenterFrequency(settings.
m_streams[istream].m_centerFrequency);
746 if (streamSettingsKeys.contains(
"frequencyShift") || force) {
747 streams->back()->setFrequencyShift(settings.
m_streams[istream].m_frequencyShift);
749 if (streamSettingsKeys.contains(
"sampleRate") || force) {
750 streams->back()->setSampleRate(settings.
m_streams[istream].m_sampleRate);
752 if (streamSettingsKeys.contains(
"log2Decim") || force) {
753 streams->back()->setLog2Decim(settings.
m_streams[istream].m_log2Decim);
755 if (streamSettingsKeys.contains(
"fcPos") || force) {
756 streams->back()->setFcPos((
int) settings.
m_streams[istream].m_fcPos);
758 if (streamSettingsKeys.contains(
"sampleSizeIndex") || force) {
759 streams->back()->setSampleSizeIndex(settings.
m_streams[istream].m_sampleSizeIndex);
761 if (streamSettingsKeys.contains(
"amplitudeBits") || force) {
762 streams->back()->setAmplitudeBits(settings.
m_streams[istream].m_amplitudeBits);
764 if (streamSettingsKeys.contains(
"autoCorrOptions") || force) {
765 streams->back()->setAutoCorrOptions((
int) settings.
m_streams[istream].m_sampleSizeIndex);
767 if (streamSettingsKeys.contains(
"modulation") || force) {
768 streams->back()->setModulation((
int) settings.
m_streams[istream].m_modulation);
770 if (streamSettingsKeys.contains(
"modulationTone")) {
771 streams->back()->setModulationTone(settings.
m_streams[istream].m_modulationTone);
773 if (streamSettingsKeys.contains(
"amModulation") || force) {
774 streams->back()->setAmModulation(settings.
m_streams[istream].m_amModulation);
776 if (streamSettingsKeys.contains(
"fmDeviation") || force) {
777 streams->back()->setFmDeviation(settings.
m_streams[istream].m_fmDeviation);
779 if (streamSettingsKeys.contains(
"dcFactor") || force) {
780 streams->back()->setDcFactor(settings.
m_streams[istream].m_dcFactor);
782 if (streamSettingsKeys.contains(
"iFactor") || force) {
783 streams->back()->setIFactor(settings.
m_streams[istream].m_iFactor);
785 if (streamSettingsKeys.contains(
"qFactor") || force) {
786 streams->back()->setQFactor(settings.
m_streams[istream].m_qFactor);
788 if (streamSettingsKeys.contains(
"phaseImbalance") || force) {
789 streams->back()->setPhaseImbalance(settings.
m_streams[istream].m_phaseImbalance);
798 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/device/settings")
803 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
805 QBuffer *buffer=
new QBuffer();
806 buffer->open((QBuffer::ReadWrite));
807 buffer->write(swgDeviceSettings->
asJson().toUtf8());
813 delete swgDeviceSettings;
823 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/device/run")
828 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
830 QBuffer *buffer=
new QBuffer();
831 buffer->open((QBuffer::ReadWrite));
832 buffer->write(swgDeviceSettings->
asJson().toUtf8());
841 delete swgDeviceSettings;
846 QNetworkReply::NetworkError replyError = reply->error();
850 qWarning() <<
"TestMI::networkManagerFinished:" 851 <<
" error(" << (int) replyError
852 <<
"): " << replyError
853 <<
": " << reply->errorString();
857 QString answer = reply->readAll();
859 qDebug(
"TestMI::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
QString m_reverseAPIAddress
virtual quint64 getSourceCenterFrequency(int index) const
Center frequency exposed by the source at index.
std::vector< FileRecord * > m_fileSinks
File sinks to record device I/Q output.
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
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)
QByteArray serialize() const
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
qint32 getReverseApiDeviceIndex()
uint getDeviceUID() const
Return the current device engine unique ID.
uint16_t m_reverseAPIPort
void setUseReverseApi(qint32 use_reverse_api)
virtual int getSourceSampleRate(int index) const
Sample rate exposed by the source at index.
virtual QString asJson() override
bool applySettings(const TestMISettings &settings, bool force)
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
int getStreamIndex() const
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
QString * getFileRecordName()
SWGTestMISettings * getTestMiSettings()
void networkManagerFinished(QNetworkReply *reply)
void setOriginatorIndex(qint32 originator_index)
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
void webapiReverseSendSettings(const DeviceSettingsKeys &deviceSettingsKeys, const TestMISettings &settings, bool force)
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
std::vector< SampleSinkFifo > m_sampleSinkFifos
Rx FIFOs.
int getDeviceSetIndex() const
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
void addAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Adds a sink to receive full baseband and that is not a channel (e.g. spectrum)
TestMISettings m_settings
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
bool isRecording(unsigned int istream) const
static MsgStartStop * create(bool startStop)
QString m_deviceDescription
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
virtual bool deserialize(const QByteArray &data)
QList< QString > m_commonSettingsKeys
uint16_t m_reverseAPIDeviceIndex
static bool match(const Message *message)
std::vector< TestMIStreamSettings > m_streams
bool deserialize(const QByteArray &data)
virtual QByteArray serialize() const
void removeAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Removes it.
bool getStartStop() const
qint32 getReverseApiPort()
std::vector< TestMIThread * > m_testSourceThreads
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
void getDeviceEngineStateStr(QString &state)
qint32 getUseReverseApi()
QList< SWGTestMiStreamSettings * > * getStreams()
void setTestMiSettings(SWGTestMISettings *test_mi_settings)
void setReverseApiAddress(QString *reverse_api_address)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
virtual const QString & getDeviceDescription() const
void setFileRecordName(QString *file_record_name)
QNetworkAccessManager * m_networkManager
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const TestMISettings &settings)
QString * getReverseApiAddress()
void webapiReverseSendStartStop(bool start)
void setReverseApiPort(qint32 reverse_api_port)
virtual void setSourceCenterFrequency(qint64 centerFrequency, int index)
MessageQueue m_inputMessageQueue
Input queue to the sink.
QList< QList< QString > > m_streamsSettingsKeys
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int streamIndex=0)
Configure current device engine DSP corrections (Rx)
bool getStartStop() const
void removeLastSourceStream()
void setDirection(qint32 direction)
QNetworkRequest m_networkRequest
void setDeviceHwType(QString *device_hw_type)
virtual bool handleMessage(const Message &message)