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.
rtlsdrinput.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
3 // written by Christian Daniel //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include <string.h>
20 #include <errno.h>
21 
22 #include <QDebug>
23 #include <QNetworkReply>
24 #include <QBuffer>
25 
26 #include "SWGDeviceSettings.h"
27 #include "SWGRtlSdrSettings.h"
28 #include "SWGDeviceState.h"
29 #include "SWGDeviceReport.h"
30 #include "SWGRtlSdrReport.h"
31 
32 #include "rtlsdrinput.h"
33 #include "device/deviceapi.h"
34 #include "rtlsdrthread.h"
35 #include "dsp/dspcommands.h"
36 #include "dsp/dspengine.h"
37 #include "dsp/filerecord.h"
38 
42 
43 const quint64 RTLSDRInput::frequencyLowRangeMin = 0UL;
44 const quint64 RTLSDRInput::frequencyLowRangeMax = 275000UL;
45 const quint64 RTLSDRInput::frequencyHighRangeMin = 24000UL;
46 const quint64 RTLSDRInput::frequencyHighRangeMax = 1900000UL;
47 const int RTLSDRInput::sampleRateLowRangeMin = 230000U;
48 const int RTLSDRInput::sampleRateLowRangeMax = 300000U;
49 const int RTLSDRInput::sampleRateHighRangeMin = 950000U;
50 const int RTLSDRInput::sampleRateHighRangeMax = 2400000U;
51 
53  m_deviceAPI(deviceAPI),
54  m_settings(),
55  m_dev(0),
56  m_rtlSDRThread(0),
57  m_deviceDescription(),
58  m_running(false)
59 {
60  openDevice();
61 
62  m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID()));
65 
66  m_networkManager = new QNetworkAccessManager();
67  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
68 }
69 
71 {
72  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
73  delete m_networkManager;
74 
75  if (m_running) {
76  stop();
77  }
78 
80  delete m_fileSink;
81 
82  closeDevice();
83 }
84 
86 {
87  delete this;
88 }
89 
91 {
92  if (m_dev != 0)
93  {
94  closeDevice();
95  }
96 
97  char vendor[256];
98  char product[256];
99  char serial[256];
100  int res;
101  int numberOfGains;
102 
103  if (!m_sampleFifo.setSize(96000 * 4))
104  {
105  qCritical("RTLSDRInput::openDevice: Could not allocate SampleFifo");
106  return false;
107  }
108 
109  int device;
110 
111  if ((device = rtlsdr_get_index_by_serial(qPrintable(m_deviceAPI->getSamplingDeviceSerial()))) < 0)
112  {
113  qCritical("RTLSDRInput::openDevice: could not get RTLSDR serial number");
114  return false;
115  }
116 
117  if ((res = rtlsdr_open(&m_dev, device)) < 0)
118  {
119  qCritical("RTLSDRInput::openDevice: could not open RTLSDR #%d: %s", device, strerror(errno));
120  return false;
121  }
122 
123  vendor[0] = '\0';
124  product[0] = '\0';
125  serial[0] = '\0';
126 
127  if ((res = rtlsdr_get_usb_strings(m_dev, vendor, product, serial)) < 0)
128  {
129  qCritical("RTLSDRInput::openDevice: error accessing USB device");
130  stop();
131  return false;
132  }
133 
134  qInfo("RTLSDRInput::openDevice: open: %s %s, SN: %s", vendor, product, serial);
135  m_deviceDescription = QString("%1 (SN %2)").arg(product).arg(serial);
136 
137  if ((res = rtlsdr_set_sample_rate(m_dev, 1152000)) < 0)
138  {
139  qCritical("RTLSDRInput::openDevice: could not set sample rate: 1024k S/s");
140  stop();
141  return false;
142  }
143 
144  if ((res = rtlsdr_set_tuner_gain_mode(m_dev, 1)) < 0)
145  {
146  qCritical("RTLSDRInput::openDevice: error setting tuner gain mode");
147  stop();
148  return false;
149  }
150 
151  if ((res = rtlsdr_set_agc_mode(m_dev, 0)) < 0)
152  {
153  qCritical("RTLSDRInput::openDevice: error setting agc mode");
154  stop();
155  return false;
156  }
157 
158  numberOfGains = rtlsdr_get_tuner_gains(m_dev, NULL);
159 
160  if (numberOfGains < 0)
161  {
162  qCritical("RTLSDRInput::openDevice: error getting number of gain values supported");
163  stop();
164  return false;
165  }
166 
167  m_gains.resize(numberOfGains);
168 
169  if (rtlsdr_get_tuner_gains(m_dev, &m_gains[0]) < 0)
170  {
171  qCritical("RTLSDRInput::openDevice: error getting gain values");
172  stop();
173  return false;
174  }
175  else
176  {
177  qDebug() << "RTLSDRInput::openDevice: " << m_gains.size() << "gains";
178  }
179 
180  if ((res = rtlsdr_reset_buffer(m_dev)) < 0)
181  {
182  qCritical("RTLSDRInput::openDevice: could not reset USB EP buffers: %s", strerror(errno));
183  stop();
184  return false;
185  }
186 
187  return true;
188 }
189 
191 {
192  applySettings(m_settings, true);
193 }
194 
196 {
197  QMutexLocker mutexLocker(&m_mutex);
198 
199  if (!m_dev) {
200  return false;
201  }
202 
203  if (m_running) stop();
204 
209 
211 
212  mutexLocker.unlock();
213 
214  applySettings(m_settings, true);
215  m_running = true;
216 
217  return true;
218 }
219 
221 {
222  if (m_dev != 0)
223  {
224  rtlsdr_close(m_dev);
225  m_dev = 0;
226  }
227 
228  m_deviceDescription.clear();
229 }
230 
232 {
233  QMutexLocker mutexLocker(&m_mutex);
234 
235  if (m_rtlSDRThread != 0)
236  {
238  delete m_rtlSDRThread;
239  m_rtlSDRThread = 0;
240  }
241 
242  m_running = false;
243 }
244 
245 QByteArray RTLSDRInput::serialize() const
246 {
247  return m_settings.serialize();
248 }
249 
250 bool RTLSDRInput::deserialize(const QByteArray& data)
251 {
252  bool success = true;
253 
254  if (!m_settings.deserialize(data))
255  {
257  success = false;
258  }
259 
261  m_inputMessageQueue.push(message);
262 
263  if (m_guiMessageQueue)
264  {
266  m_guiMessageQueue->push(messageToGUI);
267  }
268 
269  return success;
270 }
271 
272 const QString& RTLSDRInput::getDeviceDescription() const
273 {
274  return m_deviceDescription;
275 }
276 
278 {
279  int rate = m_settings.m_devSampleRate;
280  return (rate / (1<<m_settings.m_log2Decim));
281 }
282 
284 {
286 }
287 
288 void RTLSDRInput::setCenterFrequency(qint64 centerFrequency)
289 {
290  RTLSDRSettings settings = m_settings;
291  settings.m_centerFrequency = centerFrequency;
292 
293  MsgConfigureRTLSDR* message = MsgConfigureRTLSDR::create(settings, false);
294  m_inputMessageQueue.push(message);
295 
296  if (m_guiMessageQueue)
297  {
298  MsgConfigureRTLSDR* messageToGUI = MsgConfigureRTLSDR::create(settings, false);
299  m_guiMessageQueue->push(messageToGUI);
300  }
301 }
302 
304 {
305  if (MsgConfigureRTLSDR::match(message))
306  {
307  MsgConfigureRTLSDR& conf = (MsgConfigureRTLSDR&) message;
308  qDebug() << "RTLSDRInput::handleMessage: MsgConfigureRTLSDR";
309 
310  bool success = applySettings(conf.getSettings(), conf.getForce());
311 
312  if (!success)
313  {
314  qDebug("RTLSDRInput::handleMessage: config error");
315  }
316 
317  return true;
318  }
319  else if (MsgFileRecord::match(message))
320  {
321  MsgFileRecord& conf = (MsgFileRecord&) message;
322  qDebug() << "RTLSDRInput::handleMessage: MsgFileRecord: " << conf.getStartStop();
323 
324  if (conf.getStartStop())
325  {
326  if (m_settings.m_fileRecordName.size() != 0) {
328  } else {
330  }
331 
333  }
334  else
335  {
337  }
338 
339  return true;
340  }
341  else if (MsgStartStop::match(message))
342  {
343  MsgStartStop& cmd = (MsgStartStop&) message;
344  qDebug() << "RTLSDRInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
345 
346  if (cmd.getStartStop())
347  {
348  if (m_deviceAPI->initDeviceEngine()) {
350  }
351  }
352  else
353  {
355  }
356 
359  }
360 
361  return true;
362  }
363  else
364  {
365  return false;
366  }
367 }
368 
369 bool RTLSDRInput::applySettings(const RTLSDRSettings& settings, bool force)
370 {
371  bool forwardChange = false;
372  QList<QString> reverseAPIKeys;
373 
374  if ((m_settings.m_agc != settings.m_agc) || force)
375  {
376  reverseAPIKeys.append("agc");
377 
378  if (rtlsdr_set_agc_mode(m_dev, settings.m_agc ? 1 : 0) < 0) {
379  qCritical("RTLSDRInput::applySettings: could not set AGC mode %s", settings.m_agc ? "on" : "off");
380  } else {
381  qDebug("RTLSDRInput::applySettings: AGC mode %s", settings.m_agc ? "on" : "off");
382  }
383  }
384 
385  if ((m_settings.m_dcBlock != settings.m_dcBlock) || (m_settings.m_iqImbalance != settings.m_iqImbalance) || force)
386  {
387  reverseAPIKeys.append("dcBlock");
388  reverseAPIKeys.append("iqImbalance");
390  qDebug("RTLSDRInput::applySettings: corrections: DC block: %s IQ imbalance: %s",
391  settings.m_dcBlock ? "true" : "false",
392  settings.m_iqImbalance ? "true" : "false");
393  }
394 
395  if ((m_settings.m_loPpmCorrection != settings.m_loPpmCorrection) || force)
396  {
397  reverseAPIKeys.append("loPpmCorrection");
398 
399  if (m_dev != 0)
400  {
401  if (rtlsdr_set_freq_correction(m_dev, settings.m_loPpmCorrection) < 0) {
402  qCritical("RTLSDRInput::applySettings: could not set LO ppm correction: %d", settings.m_loPpmCorrection);
403  } else {
404  qDebug("RTLSDRInput::applySettings: LO ppm correction set to: %d", settings.m_loPpmCorrection);
405  }
406  }
407  }
408 
409  if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force)
410  {
411  reverseAPIKeys.append("devSampleRate");
412  forwardChange = true;
413 
414  if(m_dev != 0)
415  {
416  if( rtlsdr_set_sample_rate(m_dev, settings.m_devSampleRate) < 0)
417  {
418  qCritical("RTLSDRInput::applySettings: could not set sample rate: %d", settings.m_devSampleRate);
419  }
420  else
421  {
422  if (m_rtlSDRThread) {
424  }
425 
426  qDebug("RTLSDRInput::applySettings: sample rate set to %d", settings.m_devSampleRate);
427  }
428  }
429  }
430 
431  if ((m_settings.m_log2Decim != settings.m_log2Decim) || force)
432  {
433  reverseAPIKeys.append("log2Decim");
434  forwardChange = true;
435 
436  if (m_rtlSDRThread != 0) {
438  }
439 
440  qDebug("RTLSDRInput::applySettings: log2decim set to %d", settings.m_log2Decim);
441  }
442 
443  if ((m_settings.m_fcPos != settings.m_fcPos) || force)
444  {
445  reverseAPIKeys.append("fcPos");
446 
447  if (m_rtlSDRThread != 0) {
448  m_rtlSDRThread->setFcPos((int) settings.m_fcPos);
449  }
450 
451  qDebug() << "RTLSDRInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
452  }
453 
454  if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
455  reverseAPIKeys.append("centerFrequency");
456  }
457  if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) {
458  reverseAPIKeys.append("devSampleRate");
459  }
460  if ((m_settings.m_transverterMode != settings.m_transverterMode) || force) {
461  reverseAPIKeys.append("transverterMode");
462  }
464  reverseAPIKeys.append("transverterDeltaFrequency");
465  }
466 
468  || (m_settings.m_fcPos != settings.m_fcPos)
469  || (m_settings.m_log2Decim != settings.m_log2Decim)
473  {
474  qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency(
475  settings.m_centerFrequency,
477  settings.m_log2Decim,
479  settings.m_devSampleRate,
480  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD,
481  settings.m_transverterMode);
482 
483  forwardChange = true;
484 
485  if (m_dev != 0)
486  {
487  if (rtlsdr_set_center_freq(m_dev, deviceCenterFrequency) != 0) {
488  qWarning("RTLSDRInput::applySettings: rtlsdr_set_center_freq(%lld) failed", deviceCenterFrequency);
489  } else {
490  qDebug("RTLSDRInput::applySettings: rtlsdr_set_center_freq(%lld)", deviceCenterFrequency);
491  }
492  }
493  }
494 
495  if ((m_settings.m_noModMode != settings.m_noModMode) || force)
496  {
497  reverseAPIKeys.append("noModMode");
498  qDebug() << "RTLSDRInput::applySettings: set noModMode to " << settings.m_noModMode;
499 
500  // Direct Modes: 0: off, 1: I, 2: Q, 3: NoMod.
501  if (settings.m_noModMode) {
502  set_ds_mode(3);
503  } else {
504  set_ds_mode(0);
505  }
506  }
507 
508  if ((m_settings.m_lowSampleRate != settings.m_lowSampleRate) || force) {
509  reverseAPIKeys.append("lowSampleRate");
510  }
511 
512  if ((m_settings.m_rfBandwidth != settings.m_rfBandwidth) || force)
513  {
514  reverseAPIKeys.append("rfBandwidth");
516 
517  if (m_dev != 0)
518  {
519  if (rtlsdr_set_tuner_bandwidth( m_dev, m_settings.m_rfBandwidth) != 0) {
520  qCritical("RTLSDRInput::applySettings: could not set RF bandwidth to %u", m_settings.m_rfBandwidth);
521  } else {
522  qDebug() << "RTLSDRInput::applySettings: set RF bandwidth to " << m_settings.m_rfBandwidth;
523  }
524  }
525  }
526 
527  if ((m_settings.m_offsetTuning != settings.m_offsetTuning) || force)
528  {
529  reverseAPIKeys.append("offsetTuning");
530 
531  if (m_dev != 0)
532  {
533  if (rtlsdr_set_offset_tuning(m_dev, m_settings.m_offsetTuning ? 0 : 1) != 0) {
534  qCritical("RTLSDRInput::applySettings: could not set offset tuning to %s", settings.m_offsetTuning ? "on" : "off");
535  } else {
536  qDebug("RTLSDRInput::applySettings: offset tuning set to %s", settings.m_offsetTuning ? "on" : "off");
537  }
538  }
539  }
540 
541  if ((m_settings.m_gain != settings.m_gain) || force)
542  {
543  reverseAPIKeys.append("gain");
544 
545  if(m_dev != 0)
546  {
547  if (rtlsdr_set_tuner_gain(m_dev, settings.m_gain) != 0) {
548  qCritical("RTLSDRInput::applySettings: rtlsdr_set_tuner_gain() failed");
549  } else {
550  qDebug("RTLSDRInput::applySettings: rtlsdr_set_tuner_gain() to %d", settings.m_gain);
551  }
552  }
553  }
554 
555  if (settings.m_useReverseAPI)
556  {
557  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
561  webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
562  }
563 
564  m_settings = settings;
565 
566  if (forwardChange)
567  {
568  int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim);
570  m_fileSink->handleMessage(*notif); // forward to file sink
572  }
573 
574  return true;
575 }
576 
578 {
579  rtlsdr_set_direct_sampling(m_dev, on);
580 }
581 
584  QString& errorMessage)
585 {
586  (void) errorMessage;
588  response.getRtlSdrSettings()->init();
590  return 200;
591 }
592 
594  bool force,
595  const QStringList& deviceSettingsKeys,
596  SWGSDRangel::SWGDeviceSettings& response, // query + response
597  QString& errorMessage)
598 {
599  (void) errorMessage;
600  RTLSDRSettings settings = m_settings;
601 
602  if (deviceSettingsKeys.contains("agc")) {
603  settings.m_agc = response.getRtlSdrSettings()->getAgc() != 0;
604  }
605  if (deviceSettingsKeys.contains("centerFrequency")) {
606  settings.m_centerFrequency = response.getRtlSdrSettings()->getCenterFrequency();
607  }
608  if (deviceSettingsKeys.contains("dcBlock")) {
609  settings.m_dcBlock = response.getRtlSdrSettings()->getDcBlock() != 0;
610  }
611  if (deviceSettingsKeys.contains("devSampleRate")) {
612  settings.m_devSampleRate = response.getRtlSdrSettings()->getDevSampleRate();
613  }
614  if (deviceSettingsKeys.contains("fcPos")) {
615  settings.m_fcPos = (RTLSDRSettings::fcPos_t) response.getRtlSdrSettings()->getFcPos();
616  }
617  if (deviceSettingsKeys.contains("gain")) {
618  settings.m_gain = response.getRtlSdrSettings()->getGain();
619  }
620  if (deviceSettingsKeys.contains("iqImbalance")) {
621  settings.m_iqImbalance = response.getRtlSdrSettings()->getIqImbalance() != 0;
622  }
623  if (deviceSettingsKeys.contains("loPpmCorrection")) {
624  settings.m_loPpmCorrection = response.getRtlSdrSettings()->getLoPpmCorrection();
625  }
626  if (deviceSettingsKeys.contains("log2Decim")) {
627  settings.m_log2Decim = response.getRtlSdrSettings()->getLog2Decim();
628  }
629  if (deviceSettingsKeys.contains("lowSampleRate")) {
630  settings.m_lowSampleRate = response.getRtlSdrSettings()->getLowSampleRate() != 0;
631  }
632  if (deviceSettingsKeys.contains("noModMode")) {
633  settings.m_noModMode = response.getRtlSdrSettings()->getNoModMode() != 0;
634  }
635  if (deviceSettingsKeys.contains("offsetTuning")) {
636  settings.m_offsetTuning = response.getRtlSdrSettings()->getOffsetTuning() != 0;
637  }
638  if (deviceSettingsKeys.contains("transverterDeltaFrequency")) {
640  }
641  if (deviceSettingsKeys.contains("transverterMode")) {
642  settings.m_transverterMode = response.getRtlSdrSettings()->getTransverterMode() != 0;
643  }
644  if (deviceSettingsKeys.contains("rfBandwidth")) {
645  settings.m_rfBandwidth = response.getRtlSdrSettings()->getRfBandwidth();
646  }
647  if (deviceSettingsKeys.contains("fileRecordName")) {
648  settings.m_fileRecordName = *response.getRtlSdrSettings()->getFileRecordName();
649  }
650  if (deviceSettingsKeys.contains("useReverseAPI")) {
651  settings.m_useReverseAPI = response.getRtlSdrSettings()->getUseReverseApi() != 0;
652  }
653  if (deviceSettingsKeys.contains("reverseAPIAddress")) {
655  }
656  if (deviceSettingsKeys.contains("reverseAPIPort")) {
657  settings.m_reverseAPIPort = response.getRtlSdrSettings()->getReverseApiPort();
658  }
659  if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
661  }
662 
663  MsgConfigureRTLSDR *msg = MsgConfigureRTLSDR::create(settings, force);
665 
666  if (m_guiMessageQueue) // forward to GUI if any
667  {
668  MsgConfigureRTLSDR *msgToGUI = MsgConfigureRTLSDR::create(settings, force);
669  m_guiMessageQueue->push(msgToGUI);
670  }
671 
672  webapiFormatDeviceSettings(response, settings);
673  return 200;
674 }
675 
677 {
678  qDebug("RTLSDRInput::webapiFormatDeviceSettings: m_lowSampleRate: %s", settings.m_lowSampleRate ? "true" : "false");
679  response.getRtlSdrSettings()->setAgc(settings.m_agc ? 1 : 0);
681  response.getRtlSdrSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
682  response.getRtlSdrSettings()->setDevSampleRate(settings.m_devSampleRate);
683  response.getRtlSdrSettings()->setFcPos((int) settings.m_fcPos);
684  response.getRtlSdrSettings()->setGain(settings.m_gain);
685  response.getRtlSdrSettings()->setIqImbalance(settings.m_iqImbalance ? 1 : 0);
687  response.getRtlSdrSettings()->setLog2Decim(settings.m_log2Decim);
688  response.getRtlSdrSettings()->setLowSampleRate(settings.m_lowSampleRate ? 1 : 0);
689  response.getRtlSdrSettings()->setNoModMode(settings.m_noModMode ? 1 : 0);
690  response.getRtlSdrSettings()->setOffsetTuning(settings.m_offsetTuning ? 1 : 0);
692  response.getRtlSdrSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0);
693  response.getRtlSdrSettings()->setRfBandwidth(settings.m_rfBandwidth);
694 
695  if (response.getRtlSdrSettings()->getFileRecordName()) {
696  *response.getRtlSdrSettings()->getFileRecordName() = settings.m_fileRecordName;
697  } else {
698  response.getRtlSdrSettings()->setFileRecordName(new QString(settings.m_fileRecordName));
699  }
700 
701  response.getRtlSdrSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
702 
703  if (response.getRtlSdrSettings()->getReverseApiAddress()) {
705  } else {
706  response.getRtlSdrSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
707  }
708 
711 }
712 
714  SWGSDRangel::SWGDeviceState& response,
715  QString& errorMessage)
716 {
717  (void) errorMessage;
719  return 200;
720 }
721 
723  bool run,
724  SWGSDRangel::SWGDeviceState& response,
725  QString& errorMessage)
726 {
727  (void) errorMessage;
729  MsgStartStop *message = MsgStartStop::create(run);
730  m_inputMessageQueue.push(message);
731 
732  if (m_guiMessageQueue) // forward to GUI if any
733  {
734  MsgStartStop *msgToGUI = MsgStartStop::create(run);
735  m_guiMessageQueue->push(msgToGUI);
736  }
737 
738  return 200;
739 }
740 
743  QString& errorMessage)
744 {
745  (void) errorMessage;
747  response.getRtlSdrReport()->init();
748  webapiFormatDeviceReport(response);
749  return 200;
750 }
751 
753 {
754  response.getRtlSdrReport()->setGains(new QList<SWGSDRangel::SWGGain*>);
755 
756  for (std::vector<int>::const_iterator it = getGains().begin(); it != getGains().end(); ++it)
757  {
758  response.getRtlSdrReport()->getGains()->append(new SWGSDRangel::SWGGain);
759  response.getRtlSdrReport()->getGains()->back()->setGainCb(*it);
760  }
761 }
762 
763 void RTLSDRInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const RTLSDRSettings& settings, bool force)
764 {
766  swgDeviceSettings->setDirection(0); // single Rx
767  swgDeviceSettings->setDeviceHwType(new QString("RTLSDR"));
768  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
769  swgDeviceSettings->setRtlSdrSettings(new SWGSDRangel::SWGRtlSdrSettings());
770  SWGSDRangel::SWGRtlSdrSettings *swgRtlSdrSettings = swgDeviceSettings->getRtlSdrSettings();
771 
772  // transfer data that has been modified. When force is on transfer all data except reverse API data
773 
774  if (deviceSettingsKeys.contains("agc") || force) {
775  swgRtlSdrSettings->setAgc(settings.m_agc ? 1 : 0);
776  }
777  if (deviceSettingsKeys.contains("centerFrequency") || force) {
778  swgRtlSdrSettings->setCenterFrequency(settings.m_centerFrequency);
779  }
780  if (deviceSettingsKeys.contains("dcBlock") || force) {
781  swgRtlSdrSettings->setDcBlock(settings.m_dcBlock ? 1 : 0);
782  }
783  if (deviceSettingsKeys.contains("devSampleRate") || force) {
784  swgRtlSdrSettings->setDevSampleRate(settings.m_devSampleRate);
785  }
786  if (deviceSettingsKeys.contains("fcPos") || force) {
787  swgRtlSdrSettings->setFcPos(settings.m_fcPos);
788  }
789  if (deviceSettingsKeys.contains("gain") || force) {
790  swgRtlSdrSettings->setGain(settings.m_gain);
791  }
792  if (deviceSettingsKeys.contains("iqImbalance") || force) {
793  swgRtlSdrSettings->setIqImbalance(settings.m_iqImbalance ? 1 : 0);
794  }
795  if (deviceSettingsKeys.contains("loPpmCorrection") || force) {
796  swgRtlSdrSettings->setLoPpmCorrection(settings.m_loPpmCorrection);
797  }
798  if (deviceSettingsKeys.contains("log2Decim") || force) {
799  swgRtlSdrSettings->setLog2Decim(settings.m_log2Decim);
800  }
801  if (deviceSettingsKeys.contains("lowSampleRate") || force) {
802  swgRtlSdrSettings->setLowSampleRate(settings.m_lowSampleRate);
803  }
804  if (deviceSettingsKeys.contains("noModMode") || force) {
805  swgRtlSdrSettings->setNoModMode(settings.m_noModMode ? 1 : 0);
806  }
807  if (deviceSettingsKeys.contains("offsetTuning") || force) {
808  swgRtlSdrSettings->setOffsetTuning(settings.m_offsetTuning ? 1 : 0);
809  }
810  if (deviceSettingsKeys.contains("transverterDeltaFrequency") || force) {
811  swgRtlSdrSettings->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency);
812  }
813  if (deviceSettingsKeys.contains("transverterMode") || force) {
814  swgRtlSdrSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0);
815  }
816  if (deviceSettingsKeys.contains("rfBandwidth") || force) {
817  swgRtlSdrSettings->setRfBandwidth(settings.m_rfBandwidth);
818  }
819  if (deviceSettingsKeys.contains("fileRecordName") || force) {
820  swgRtlSdrSettings->setFileRecordName(new QString(settings.m_fileRecordName));
821  }
822 
823  QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
824  .arg(settings.m_reverseAPIAddress)
825  .arg(settings.m_reverseAPIPort)
826  .arg(settings.m_reverseAPIDeviceIndex);
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  // Always use PATCH to avoid passing reverse API settings
836  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
837 
838  delete swgDeviceSettings;
839 }
840 
842 {
844  swgDeviceSettings->setDirection(0); // single Rx
845  swgDeviceSettings->setDeviceHwType(new QString("RTLSDR"));
846  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
847 
848  QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
852  m_networkRequest.setUrl(QUrl(channelSettingsURL));
853  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
854 
855  QBuffer *buffer=new QBuffer();
856  buffer->open((QBuffer::ReadWrite));
857  buffer->write(swgDeviceSettings->asJson().toUtf8());
858  buffer->seek(0);
859 
860  if (start) {
861  m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
862  } else {
863  m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
864  }
865 
866  delete swgDeviceSettings;
867 }
868 
869 void RTLSDRInput::networkManagerFinished(QNetworkReply *reply)
870 {
871  QNetworkReply::NetworkError replyError = reply->error();
872 
873  if (replyError)
874  {
875  qWarning() << "TestSourceInput::networkManagerFinished:"
876  << " error(" << (int) replyError
877  << "): " << replyError
878  << ": " << reply->errorString();
879  return;
880  }
881 
882  QString answer = reply->readAll();
883  answer.chop(1); // remove last \n
884  qDebug("RTLSDRInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
885 }
QNetworkAccessManager * m_networkManager
Definition: rtlsdrinput.h:165
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
void closeDevice()
bool openDevice()
Definition: rtlsdrinput.cpp:90
void setSamplerate(int samplerate)
void setLowSampleRate(qint32 low_sample_rate)
QNetworkRequest m_networkRequest
Definition: rtlsdrinput.h:166
virtual quint64 getCenterFrequency() const
Center frequency exposed by the source.
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.
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
Definition: deviceapi.cpp:266
static const quint64 frequencyLowRangeMin
Definition: rtlsdrinput.h:146
QList< SWGGain * > * getGains()
void setFileName(const QString &filename)
Definition: filerecord.cpp:59
uint getDeviceUID() const
Return the current device engine unique ID.
Definition: deviceapi.cpp:303
void setNbSourceStreams(uint32_t nbSourceStreams)
Definition: deviceapi.h:168
static const int sampleRateHighRangeMax
Definition: rtlsdrinput.h:153
void startRecording()
Definition: filerecord.cpp:105
FileRecord * m_fileSink
File sink to record device I/Q output.
Definition: rtlsdrinput.h:157
MessageQueue m_inputMessageQueue
Input queue to the source.
virtual QString asJson() override
QByteArray serialize() const
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
void startWork()
static MsgConfigureRTLSDR * create(const RTLSDRSettings &settings, bool force)
Definition: rtlsdrinput.h:46
RTLSDRInput(DeviceAPI *deviceAPI)
Definition: rtlsdrinput.cpp:52
SWGRtlSdrSettings * getRtlSdrSettings()
bool applySettings(const RTLSDRSettings &settings, bool force)
void setDevSampleRate(qint32 dev_sample_rate)
virtual bool deserialize(const QByteArray &data)
QString m_fileRecordName
void setOffsetTuning(qint32 offset_tuning)
void setTransverterDeltaFrequency(qint64 transverter_delta_frequency)
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
virtual int getSampleRate() const
Sample rate exposed by the source.
bool getStartStop() const
Definition: rtlsdrinput.h:85
static const int sampleRateHighRangeMin
Definition: rtlsdrinput.h:152
void setIqImbalance(qint32 iq_imbalance)
void setOriginatorIndex(qint32 originator_index)
virtual bool start()
SampleSinkFifo m_sampleFifo
bool setSize(int size)
void setNoModMode(qint32 no_mod_mode)
void setFcPos(int fcPos)
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
virtual bool handleMessage(const Message &message)
Processing of a message. Returns true if message has actually been processed.
Definition: filerecord.cpp:128
void setLog2Decimation(unsigned int log2_decim)
void webapiReverseSendStartStop(bool start)
uint16_t m_reverseAPIDeviceIndex
uint16_t m_reverseAPIPort
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
int getDeviceSetIndex() const
Definition: deviceapi.h:131
void setGains(QList< SWGGain *> *gains)
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
Definition: message.h:52
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
virtual bool handleMessage(const Message &message)
void genUniqueFileName(uint deviceUID, int istream=-1)
Definition: filerecord.cpp:67
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
void setReverseApiAddress(QString *reverse_api_address)
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
static MsgStartStop * create(bool startStop)
Definition: rtlsdrinput.h:87
RTLSDRSettings m_settings
Definition: rtlsdrinput.h:159
void stopRecording()
Definition: filerecord.cpp:117
virtual int webapiReportGet(SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
void setRtlSdrReport(SWGRtlSdrReport *rtl_sdr_report)
RTLSDRThread * m_rtlSDRThread
Definition: rtlsdrinput.h:161
static const quint64 frequencyHighRangeMax
Definition: rtlsdrinput.h:149
static bool match(const Message *message)
Definition: message.cpp:45
virtual ~RTLSDRInput()
Definition: rtlsdrinput.cpp:70
virtual const QString & getDeviceDescription() const
std::vector< int > m_gains
Definition: rtlsdrinput.h:163
DeviceAPI * m_deviceAPI
Definition: rtlsdrinput.h:156
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
void removeAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Removes it.
Definition: deviceapi.cpp:100
virtual void setCenterFrequency(qint64 centerFrequency)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
quint32 m_log2Decim
QMutex m_mutex
Definition: rtlsdrinput.h:158
quint32 m_rfBandwidth
RF filter bandwidth in Hz.
qint32 m_loPpmCorrection
void setRtlSdrSettings(SWGRtlSdrSettings *rtl_sdr_settings)
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
void setReverseApiPort(qint32 reverse_api_port)
void set_ds_mode(int on)
bool m_running
Definition: rtlsdrinput.h:164
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const RTLSDRSettings &settings)
const QString & getSamplingDeviceSerial() const
Definition: deviceapi.h:121
static const int sampleRateLowRangeMax
Definition: rtlsdrinput.h:151
virtual void stop()
void setCenterFrequency(qint64 center_frequency)
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const RTLSDRSettings &settings, bool force)
QString m_reverseAPIAddress
void setUseReverseApi(qint32 use_reverse_api)
const std::vector< int > & getGains() const
Definition: rtlsdrinput.h:143
void setFileRecordName(QString *file_record_name)
virtual QByteArray serialize() const
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
void setTransverterMode(qint32 transverter_mode)
qint64 m_transverterDeltaFrequency
void networkManagerFinished(QNetworkReply *reply)
SWGRtlSdrReport * getRtlSdrReport()
const RTLSDRSettings & getSettings() const
Definition: rtlsdrinput.h:43
void setRfBandwidth(qint32 rf_bandwidth)
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
quint64 m_centerFrequency
bool deserialize(const QByteArray &data)
static const int sampleRateLowRangeMin
Definition: rtlsdrinput.h:150
void setLoPpmCorrection(qint32 lo_ppm_correction)
QString m_deviceDescription
Definition: rtlsdrinput.h:162
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int streamIndex=0)
Configure current device engine DSP corrections (Rx)
Definition: deviceapi.cpp:355
void setLog2Decim(qint32 log2_decim)
void setDirection(qint32 direction)
virtual void destroy()
Definition: rtlsdrinput.cpp:85
rtlsdr_dev_t * m_dev
Definition: rtlsdrinput.h:160
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport &response)
static const quint64 frequencyHighRangeMin
Definition: rtlsdrinput.h:148
void setDeviceHwType(QString *device_hw_type)
static const quint64 frequencyLowRangeMax
Definition: rtlsdrinput.h:147