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.
bladerf1input.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015 Edouard Griffiths, F4EXB //
3 // //
4 // This program is free software; you can redistribute it and/or modify //
5 // it under the terms of the GNU General Public License as published by //
6 // the Free Software Foundation as version 3 of the License, or //
7 // (at your option) any later version. //
8 // //
9 // This program is distributed in the hope that it will be useful, //
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
12 // GNU General Public License V3 for more details. //
13 // //
14 // You should have received a copy of the GNU General Public License //
15 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
17 
18 #include <string.h>
19 #include <errno.h>
20 
21 #include <QDebug>
22 #include <QNetworkReply>
23 #include <QBuffer>
24 
25 #include "SWGDeviceSettings.h"
26 #include "SWGDeviceState.h"
27 
28 #include "util/simpleserializer.h"
29 #include "dsp/dspcommands.h"
32 #include "dsp/dspengine.h"
33 #include "dsp/filerecord.h"
34 #include "device/deviceapi.h"
35 
36 #include "bladerf1input.h"
37 #include "bladerf1inputthread.h"
38 
42 
44  m_deviceAPI(deviceAPI),
45  m_settings(),
46  m_dev(0),
47  m_bladerfThread(0),
48  m_deviceDescription("BladeRFInput"),
49  m_running(false)
50 {
51  openDevice();
52  m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID()));
53  m_deviceAPI->setNbSourceStreams(1);
54  m_deviceAPI->addAncillarySink(m_fileSink);
55 
56  m_deviceAPI->setBuddySharedPtr(&m_sharedParams);
57 
58  m_networkManager = new QNetworkAccessManager();
59  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
60 }
61 
63 {
64  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
65  delete m_networkManager;
66 
67  if (m_running) {
68  stop();
69  }
70 
72  delete m_fileSink;
73  closeDevice();
75 }
76 
78 {
79  delete this;
80 }
81 
83 {
84  if (m_dev != 0)
85  {
86  closeDevice();
87  }
88 
89  int res;
90 
91  if (!m_sampleFifo.setSize(96000 * 4))
92  {
93  qCritical("BladerfInput::openDevice: could not allocate SampleFifo");
94  return false;
95  }
96 
97  if (m_deviceAPI->getSinkBuddies().size() > 0)
98  {
99  DeviceAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0];
100  DeviceBladeRF1Params *buddySharedParams = (DeviceBladeRF1Params *) sinkBuddy->getBuddySharedPtr();
101 
102  if (buddySharedParams == 0)
103  {
104  qCritical("BladerfInput::openDevice: could not get shared parameters from buddy");
105  return false;
106  }
107 
108  if (buddySharedParams->m_dev == 0) // device is not opened by buddy
109  {
110  qCritical("BladerfInput::openDevice: could not get BladeRF handle from buddy");
111  return false;
112  }
113 
114  m_sharedParams = *(buddySharedParams); // copy parameters from buddy
115  m_dev = m_sharedParams.m_dev; // get BladeRF handle
116  }
117  else
118  {
120  {
121  qCritical("BladerfInput::start: could not open BladeRF %s", qPrintable(m_deviceAPI->getSamplingDeviceSerial()));
122  return false;
123  }
124 
126  }
127 
128  // TODO: adjust USB transfer data according to sample rate
129  if ((res = bladerf_sync_config(m_dev, BLADERF_RX_X1, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000)) < 0)
130  {
131  qCritical("BladerfInput::start: bladerf_sync_config with return code %d", res);
132  return false;
133  }
134 
135  if ((res = bladerf_enable_module(m_dev, BLADERF_MODULE_RX, true)) < 0)
136  {
137  qCritical("BladerfInput::start: bladerf_enable_module with return code %d", res);
138  return false;
139  }
140 
141  return true;
142 }
143 
145 {
146  applySettings(m_settings, true);
147 }
148 
150 {
151 // QMutexLocker mutexLocker(&m_mutex);
152 
153  if (!m_dev)
154  {
155  qDebug("BladerfInput::start: no device handle");
156  return false;
157  }
158 
159  if (m_running) stop();
160 
164 
166 
167 // mutexLocker.unlock();
168  applySettings(m_settings, true);
169 
170  qDebug("BladerfInput::startInput: started");
171  m_running = true;
172 
173  return true;
174 }
175 
177 {
178  int res;
179 
180  if (m_dev == 0) { // was never open
181  return;
182  }
183 
184  if ((res = bladerf_enable_module(m_dev, BLADERF_MODULE_RX, false)) < 0)
185  {
186  qCritical("BladerfInput::stop: bladerf_enable_module with return code %d", res);
187  }
188 
189  if (m_deviceAPI->getSinkBuddies().size() == 0)
190  {
191  qDebug("BladerfInput::closeDevice: closing device since Tx side is not open");
192 
193  if(m_dev != 0) // close BladeRF
194  {
195  bladerf_close(m_dev);
196  }
197  }
198 
199  m_sharedParams.m_dev = 0;
200  m_dev = 0;
201 }
202 
204 {
205 // QMutexLocker mutexLocker(&m_mutex);
206 
207  if(m_bladerfThread != 0)
208  {
210  delete m_bladerfThread;
211  m_bladerfThread = 0;
212  }
213 
214  m_running = false;
215 }
216 
217 QByteArray Bladerf1Input::serialize() const
218 {
219  return m_settings.serialize();
220 }
221 
222 bool Bladerf1Input::deserialize(const QByteArray& data)
223 {
224  bool success = true;
225 
226  if (!m_settings.deserialize(data))
227  {
229  success = false;
230  }
231 
233  m_inputMessageQueue.push(message);
234 
235  if (m_guiMessageQueue)
236  {
238  m_guiMessageQueue->push(messageToGUI);
239  }
240 
241  return success;
242 }
243 
245 {
246  return m_deviceDescription;
247 }
248 
250 {
251  int rate = m_settings.m_devSampleRate;
252  return (rate / (1<<m_settings.m_log2Decim));
253 }
254 
256 {
258 }
259 
260 void Bladerf1Input::setCenterFrequency(qint64 centerFrequency)
261 {
263  settings.m_centerFrequency = centerFrequency;
264 
265  MsgConfigureBladerf1* message = MsgConfigureBladerf1::create(settings, false);
266  m_inputMessageQueue.push(message);
267 
268  if (m_guiMessageQueue)
269  {
270  MsgConfigureBladerf1* messageToGUI = MsgConfigureBladerf1::create(settings, false);
271  m_guiMessageQueue->push(messageToGUI);
272  }
273 }
274 
276 {
277  if (MsgConfigureBladerf1::match(message))
278  {
279  MsgConfigureBladerf1& conf = (MsgConfigureBladerf1&) message;
280  qDebug() << "Bladerf1Input::handleMessage: MsgConfigureBladerf1";
281 
282  if (!applySettings(conf.getSettings(), conf.getForce()))
283  {
284  qDebug("BladeRF config error");
285  }
286 
287  return true;
288  }
289  else if (MsgFileRecord::match(message))
290  {
291  MsgFileRecord& conf = (MsgFileRecord&) message;
292  qDebug() << "BladerfInput::handleMessage: MsgFileRecord: " << conf.getStartStop();
293 
294  if (conf.getStartStop())
295  {
296  if (m_settings.m_fileRecordName.size() != 0) {
298  } else {
300  }
301 
303  }
304  else
305  {
307  }
308 
309  return true;
310  }
311  else if (MsgStartStop::match(message))
312  {
313  MsgStartStop& cmd = (MsgStartStop&) message;
314  qDebug() << "BladerfInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
315 
316  if (cmd.getStartStop())
317  {
319  {
321  }
322  }
323  else
324  {
326  }
327 
330  }
331 
332  return true;
333  }
334  else
335  {
336  return false;
337  }
338 }
339 
340 bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, bool force)
341 {
342  bool forwardChange = false;
343  QList<QString> reverseAPIKeys;
344 // QMutexLocker mutexLocker(&m_mutex);
345 
346  qDebug() << "BladerfInput::applySettings: m_dev: " << m_dev;
347 
348  if ((m_settings.m_dcBlock != settings.m_dcBlock) || force) {
349  reverseAPIKeys.append("dcBlock");
350  }
351  if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force) {
352  reverseAPIKeys.append("iqCorrection");
353  }
354 
355  if ((m_settings.m_dcBlock != settings.m_dcBlock) ||
356  (m_settings.m_iqCorrection != settings.m_iqCorrection) || force)
357  {
359  }
360 
361  if ((m_settings.m_lnaGain != settings.m_lnaGain) || force)
362  {
363  reverseAPIKeys.append("lnaGain");
364 
365  if (m_dev != 0)
366  {
367  if(bladerf_set_lna_gain(m_dev, getLnaGain(settings.m_lnaGain)) != 0) {
368  qDebug("BladerfInput::applySettings: bladerf_set_lna_gain() failed");
369  } else {
370  qDebug() << "BladerfInput::applySettings: LNA gain set to " << getLnaGain(settings.m_lnaGain);
371  }
372  }
373  }
374 
375  if ((m_settings.m_vga1 != settings.m_vga1) || force)
376  {
377  reverseAPIKeys.append("vga1");
378 
379  if (m_dev != 0)
380  {
381  if(bladerf_set_rxvga1(m_dev, settings.m_vga1) != 0) {
382  qDebug("BladerfInput::applySettings: bladerf_set_rxvga1() failed");
383  } else {
384  qDebug() << "BladerfInput::applySettings: VGA1 gain set to " << settings.m_vga1;
385  }
386  }
387  }
388 
389  if ((m_settings.m_vga2 != settings.m_vga2) || force)
390  {
391  reverseAPIKeys.append("vga2");
392 
393  if(m_dev != 0)
394  {
395  if(bladerf_set_rxvga2(m_dev, settings.m_vga2) != 0) {
396  qDebug("BladerfInput::applySettings: bladerf_set_rxvga2() failed");
397  } else {
398  qDebug() << "BladerfInput::applySettings: VGA2 gain set to " << settings.m_vga2;
399  }
400  }
401  }
402 
403  if ((m_settings.m_xb200 != settings.m_xb200) || force)
404  {
405  reverseAPIKeys.append("xb200");
406 
407  if (m_dev != 0)
408  {
409  bool changeSettings;
410 
411  if (m_deviceAPI->getSinkBuddies().size() > 0)
412  {
413  DeviceAPI *buddy = m_deviceAPI->getSinkBuddies()[0];
414 
415  if (buddy->getDeviceSinkEngine()->state() == DSPDeviceSinkEngine::StRunning) { // Tx side running
416  changeSettings = false;
417  } else {
418  changeSettings = true;
419  }
420  }
421  else // No Tx open
422  {
423  changeSettings = true;
424  }
425 
426  if (changeSettings)
427  {
428  if (settings.m_xb200)
429  {
430  if (bladerf_expansion_attach(m_dev, BLADERF_XB_200) != 0) {
431  qDebug("BladerfInput::applySettings: bladerf_expansion_attach(xb200) failed");
432  } else {
433  qDebug() << "BladerfInput::applySettings: Attach XB200";
434  }
435  }
436  else
437  {
438  if (bladerf_expansion_attach(m_dev, BLADERF_XB_NONE) != 0) {
439  qDebug("BladerfInput::applySettings: bladerf_expansion_attach(none) failed");
440  } else {
441  qDebug() << "BladerfInput::applySettings: Detach XB200";
442  }
443  }
444 
446  }
447  }
448  }
449 
450  if ((m_settings.m_xb200Path != settings.m_xb200Path) || force)
451  {
452  reverseAPIKeys.append("xb200Path");
453 
454  if (m_dev != 0)
455  {
456  if(bladerf_xb200_set_path(m_dev, BLADERF_MODULE_RX, settings.m_xb200Path) != 0) {
457  qDebug("BladerfInput::applySettings: bladerf_xb200_set_path(BLADERF_MODULE_RX) failed");
458  } else {
459  qDebug() << "BladerfInput::applySettings: set xb200 path to " << settings.m_xb200Path;
460  }
461  }
462  }
463 
464  if ((m_settings.m_xb200Filter != settings.m_xb200Filter) || force)
465  {
466  reverseAPIKeys.append("xb200Filter");
467 
468  if (m_dev != 0)
469  {
470  if(bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_RX, settings.m_xb200Filter) != 0) {
471  qDebug("BladerfInput::applySettings: bladerf_xb200_set_filterbank(BLADERF_MODULE_RX) failed");
472  } else {
473  qDebug() << "BladerfInput::applySettings: set xb200 filter to " << settings.m_xb200Filter;
474  }
475  }
476  }
477 
478  if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force)
479  {
480  reverseAPIKeys.append("devSampleRate");
481  forwardChange = true;
482 
483  if (m_dev != 0)
484  {
485  unsigned int actualSamplerate;
486 
487  if (bladerf_set_sample_rate(m_dev, BLADERF_MODULE_RX, settings.m_devSampleRate, &actualSamplerate) < 0) {
488  qCritical("BladerfInput::applySettings: could not set sample rate: %d", settings.m_devSampleRate);
489  } else {
490  qDebug() << "BladerfInput::applySettings: bladerf_set_sample_rate(BLADERF_MODULE_RX) actual sample rate is " << actualSamplerate;
491  }
492  }
493  }
494 
495  if ((m_settings.m_bandwidth != settings.m_bandwidth) || force)
496  {
497  reverseAPIKeys.append("bandwidth");
498 
499  if(m_dev != 0)
500  {
501  unsigned int actualBandwidth;
502 
503  if( bladerf_set_bandwidth(m_dev, BLADERF_MODULE_RX, settings.m_bandwidth, &actualBandwidth) < 0) {
504  qCritical("BladerfInput::applySettings: could not set bandwidth: %d", settings.m_bandwidth);
505  } else {
506  qDebug() << "BladerfInput::applySettings: bladerf_set_bandwidth(BLADERF_MODULE_RX) actual bandwidth is " << actualBandwidth;
507  }
508  }
509  }
510 
511  if ((m_settings.m_fcPos != settings.m_fcPos) || force)
512  {
513  reverseAPIKeys.append("fcPos");
514 
515  if (m_bladerfThread != 0)
516  {
517  m_bladerfThread->setFcPos((int) settings.m_fcPos);
518  qDebug() << "BladerfInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
519  }
520  }
521 
522  if ((m_settings.m_log2Decim != settings.m_log2Decim) || force)
523  {
524  reverseAPIKeys.append("log2Decim");
525  forwardChange = true;
526 
527  if (m_bladerfThread != 0)
528  {
530  qDebug() << "BladerfInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
531  }
532  }
533 
534  if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
535  reverseAPIKeys.append("centerFrequency");
536  }
537 
540  || (m_settings.m_fcPos != settings.m_fcPos)
541  || (m_settings.m_log2Decim != settings.m_log2Decim) || force)
542  {
543  qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency(
544  settings.m_centerFrequency,
545  0,
546  settings.m_log2Decim,
548  settings.m_devSampleRate,
549  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD,
550  false);
551 
552  forwardChange = true;
553 
554  if (m_dev != 0)
555  {
556  if (bladerf_set_frequency( m_dev, BLADERF_MODULE_RX, deviceCenterFrequency ) != 0) {
557  qWarning("BladerfInput::applySettings: bladerf_set_frequency(%lld) failed", settings.m_centerFrequency);
558  } else {
559  qDebug("BladerfInput::applySettings: bladerf_set_frequency(%lld)", settings.m_centerFrequency);
560  }
561  }
562  }
563 
564  if (forwardChange)
565  {
566  int sampleRate = settings.m_devSampleRate/(1<<settings.m_log2Decim);
567  DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency);
568  m_fileSink->handleMessage(*notif); // forward to file sink
570  }
571 
572  if (settings.m_useReverseAPI)
573  {
574  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
578  webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
579  }
580 
581  m_settings = settings;
582 
583  qDebug() << "BladerfInput::applySettings: "
584  << " m_centerFrequency: " << m_settings.m_centerFrequency << " Hz"
585  << " m_bandwidth: " << m_settings.m_bandwidth
586  << " m_lnaGain: " << m_settings.m_lnaGain
587  << " m_vga1: " << m_settings.m_vga1
588  << " m_vga2: " << m_settings.m_vga2
589  << " m_log2Decim: " << m_settings.m_log2Decim
590  << " m_fcPos: " << m_settings.m_fcPos
591  << " m_devSampleRate: " << m_settings.m_devSampleRate
592  << " m_dcBlock: " << m_settings.m_dcBlock
593  << " m_iqCorrection: " << m_settings.m_iqCorrection
594  << " m_xb200Filter: " << m_settings.m_xb200Filter
595  << " m_xb200Path: " << m_settings.m_xb200Path
596  << " m_xb200: " << m_settings.m_xb200;
597 
598  return true;
599 }
600 
601 bladerf_lna_gain Bladerf1Input::getLnaGain(int lnaGain)
602 {
603  if (lnaGain == 2)
604  {
605  return BLADERF_LNA_GAIN_MAX;
606  }
607  else if (lnaGain == 1)
608  {
609  return BLADERF_LNA_GAIN_MID;
610  }
611  else
612  {
613  return BLADERF_LNA_GAIN_BYPASS;
614  }
615 }
616 
619  QString& errorMessage)
620 {
621  (void) errorMessage;
623  response.getBladeRf1InputSettings()->init();
625  return 200;
626 }
627 
629 {
632  response.getBladeRf1InputSettings()->setLnaGain(settings.m_lnaGain);
633  response.getBladeRf1InputSettings()->setVga1(settings.m_vga1);
634  response.getBladeRf1InputSettings()->setVga2(settings.m_vga2);
635  response.getBladeRf1InputSettings()->setBandwidth(settings.m_bandwidth);
636  response.getBladeRf1InputSettings()->setLog2Decim(settings.m_log2Decim);
637  response.getBladeRf1InputSettings()->setFcPos((int) settings.m_fcPos);
638  response.getBladeRf1InputSettings()->setXb200(settings.m_xb200 ? 1 : 0);
639  response.getBladeRf1InputSettings()->setXb200Path((int) settings.m_xb200Path);
640  response.getBladeRf1InputSettings()->setXb200Filter((int) settings.m_xb200Filter);
641  response.getBladeRf1InputSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
642  response.getBladeRf1InputSettings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
643 
644  if (response.getBladeRf1InputSettings()->getFileRecordName()) {
646  } else {
647  response.getBladeRf1InputSettings()->setFileRecordName(new QString(settings.m_fileRecordName));
648  }
649 
650  response.getBladeRf1InputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
651 
654  } else {
655  response.getBladeRf1InputSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
656  }
657 
660 }
661 
663  bool force,
664  const QStringList& deviceSettingsKeys,
665  SWGSDRangel::SWGDeviceSettings& response, // query + response
666  QString& errorMessage)
667 {
668  (void) errorMessage;
670 
671  if (deviceSettingsKeys.contains("centerFrequency")) {
673  }
674  if (deviceSettingsKeys.contains("devSampleRate")) {
676  }
677  if (deviceSettingsKeys.contains("lnaGain")) {
678  settings.m_lnaGain = response.getBladeRf1InputSettings()->getLnaGain();
679  }
680  if (deviceSettingsKeys.contains("vga1")) {
681  settings.m_vga1 = response.getBladeRf1InputSettings()->getVga1();
682  }
683  if (deviceSettingsKeys.contains("vga2")) {
684  settings.m_vga2 = response.getBladeRf1InputSettings()->getVga2();
685  }
686  if (deviceSettingsKeys.contains("bandwidth")) {
687  settings.m_bandwidth = response.getBladeRf1InputSettings()->getBandwidth();
688  }
689  if (deviceSettingsKeys.contains("log2Decim")) {
690  settings.m_log2Decim = response.getBladeRf1InputSettings()->getLog2Decim();
691  }
692  if (deviceSettingsKeys.contains("fcPos")) {
693  settings.m_fcPos = static_cast<BladeRF1InputSettings::fcPos_t>(response.getBladeRf1InputSettings()->getFcPos());
694  }
695  if (deviceSettingsKeys.contains("xb200")) {
696  settings.m_xb200 = response.getBladeRf1InputSettings()->getXb200() == 0 ? 0 : 1;
697  }
698  if (deviceSettingsKeys.contains("xb200Path")) {
699  settings.m_xb200Path = static_cast<bladerf_xb200_path>(response.getBladeRf1InputSettings()->getXb200Path());
700  }
701  if (deviceSettingsKeys.contains("xb200Filter")) {
702  settings.m_xb200Filter = static_cast<bladerf_xb200_filter>(response.getBladeRf1InputSettings()->getXb200Filter());
703  }
704  if (deviceSettingsKeys.contains("dcBlock")) {
705  settings.m_dcBlock = response.getBladeRf1InputSettings()->getDcBlock() != 0;
706  }
707  if (deviceSettingsKeys.contains("iqCorrection")) {
708  settings.m_iqCorrection = response.getBladeRf1InputSettings()->getIqCorrection() != 0;
709  }
710  if (deviceSettingsKeys.contains("fileRecordName")) {
712  }
713  if (deviceSettingsKeys.contains("useReverseAPI")) {
714  settings.m_useReverseAPI = response.getBladeRf1InputSettings()->getUseReverseApi() != 0;
715  }
716  if (deviceSettingsKeys.contains("reverseAPIAddress")) {
718  }
719  if (deviceSettingsKeys.contains("reverseAPIPort")) {
721  }
722  if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
724  }
725 
726  MsgConfigureBladerf1 *msg = MsgConfigureBladerf1::create(settings, force);
728 
729  if (m_guiMessageQueue) // forward to GUI if any
730  {
731  MsgConfigureBladerf1 *msgToGUI = MsgConfigureBladerf1::create(settings, force);
732  m_guiMessageQueue->push(msgToGUI);
733  }
734 
735  webapiFormatDeviceSettings(response, settings);
736  return 200;
737 }
738 
740  SWGSDRangel::SWGDeviceState& response,
741  QString& errorMessage)
742 {
743  (void) errorMessage;
745  return 200;
746 }
747 
749  bool run,
750  SWGSDRangel::SWGDeviceState& response,
751  QString& errorMessage)
752 {
753  (void) errorMessage;
755  MsgStartStop *message = MsgStartStop::create(run);
756  m_inputMessageQueue.push(message);
757 
758  if (m_guiMessageQueue) // forward to GUI if any
759  {
760  MsgStartStop *msgToGUI = MsgStartStop::create(run);
761  m_guiMessageQueue->push(msgToGUI);
762  }
763 
764  return 200;
765 }
766 
767 void Bladerf1Input::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const BladeRF1InputSettings& settings, bool force)
768 {
770  swgDeviceSettings->setDirection(0); // single Rx
771  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
772  swgDeviceSettings->setDeviceHwType(new QString("BladeRF1"));
774  SWGSDRangel::SWGBladeRF1InputSettings *swgBladeRF1Settings = swgDeviceSettings->getBladeRf1InputSettings();
775 
776  // transfer data that has been modified. When force is on transfer all data except reverse API data
777 
778  if (deviceSettingsKeys.contains("centerFrequency") || force) {
779  swgBladeRF1Settings->setCenterFrequency(settings.m_centerFrequency);
780  }
781  if (deviceSettingsKeys.contains("devSampleRate") || force) {
782  swgBladeRF1Settings->setDevSampleRate(settings.m_devSampleRate);
783  }
784  if (deviceSettingsKeys.contains("lnaGain") || force) {
785  swgBladeRF1Settings->setLnaGain(settings.m_lnaGain);
786  }
787  if (deviceSettingsKeys.contains("vga1") || force) {
788  swgBladeRF1Settings->setVga1(settings.m_vga1);
789  }
790  if (deviceSettingsKeys.contains("vga2") || force) {
791  swgBladeRF1Settings->setVga1(settings.m_vga2);
792  }
793  if (deviceSettingsKeys.contains("bandwidth") || force) {
794  swgBladeRF1Settings->setBandwidth(settings.m_bandwidth);
795  }
796  if (deviceSettingsKeys.contains("log2Decim") || force) {
797  swgBladeRF1Settings->setLog2Decim(settings.m_log2Decim);
798  }
799  if (deviceSettingsKeys.contains("fcPos") || force) {
800  swgBladeRF1Settings->setFcPos((int) settings.m_fcPos);
801  }
802  if (deviceSettingsKeys.contains("xb200") || force) {
803  swgBladeRF1Settings->setXb200(settings.m_xb200 ? 1 : 0);
804  }
805  if (deviceSettingsKeys.contains("xb200Path") || force) {
806  swgBladeRF1Settings->setXb200Path((int) settings.m_xb200Path);
807  }
808  if (deviceSettingsKeys.contains("xb200Filter") || force) {
809  swgBladeRF1Settings->setXb200Filter((int) settings.m_xb200Filter);
810  }
811  if (deviceSettingsKeys.contains("dcBlock") || force) {
812  swgBladeRF1Settings->setDcBlock(settings.m_dcBlock ? 1 : 0);
813  }
814  if (deviceSettingsKeys.contains("iqCorrection") || force) {
815  swgBladeRF1Settings->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
816  }
817  if (deviceSettingsKeys.contains("fileRecordName") || force) {
818  swgBladeRF1Settings->setFileRecordName(new QString(settings.m_fileRecordName));
819  }
820 
821  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
822  .arg(settings.m_reverseAPIAddress)
823  .arg(settings.m_reverseAPIPort)
824  .arg(settings.m_reverseAPIDeviceIndex);
825  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
826  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
827 
828  QBuffer *buffer=new QBuffer();
829  buffer->open((QBuffer::ReadWrite));
830  buffer->write(swgDeviceSettings->asJson().toUtf8());
831  buffer->seek(0);
832 
833  // Always use PATCH to avoid passing reverse API settings
834  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
835 
836  delete swgDeviceSettings;
837 }
838 
840 {
842  swgDeviceSettings->setDirection(0); // single Rx
843  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
844  swgDeviceSettings->setDeviceHwType(new QString("BladeRF1"));
845 
846  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
850  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
851  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
852 
853  QBuffer *buffer=new QBuffer();
854  buffer->open((QBuffer::ReadWrite));
855  buffer->write(swgDeviceSettings->asJson().toUtf8());
856  buffer->seek(0);
857 
858  if (start) {
859  m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
860  } else {
861  m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
862  }
863 
864  delete swgDeviceSettings;
865 }
866 
867 void Bladerf1Input::networkManagerFinished(QNetworkReply *reply)
868 {
869  QNetworkReply::NetworkError replyError = reply->error();
870 
871  if (replyError)
872  {
873  qWarning() << "Bladerf1Input::networkManagerFinished:"
874  << " error(" << (int) replyError
875  << "): " << replyError
876  << ": " << reply->errorString();
877  return;
878  }
879 
880  QString answer = reply->readAll();
881  answer.chop(1); // remove last \n
882  qDebug("Bladerf1Input::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
883 }
static bool open_bladerf(struct bladerf **dev, const char *serial)
bool m_xb200Attached
true if XB200 is attached and owned by the party
void setReverseApiAddress(QString *reverse_api_address)
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
void setBladeRf1InputSettings(SWGBladeRF1InputSettings *blade_rf1_input_settings)
static qint64 calculateDeviceCenterFrequency(quint64 centerFrequency, qint64 transverterDeltaFrequency, int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme, bool transverterMode=false)
bladerf_lna_gain getLnaGain(int lnaGain)
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
void setFileName(const QString &filename)
Definition: filerecord.cpp:59
uint getDeviceUID() const
Return the current device engine unique ID.
Definition: deviceapi.cpp:303
State state() const
Return DSP engine current state.
const BladeRF1InputSettings & getSettings() const
Definition: bladerf1input.h:45
void setFileRecordName(QString *file_record_name)
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
void startRecording()
Definition: filerecord.cpp:105
MessageQueue m_inputMessageQueue
Input queue to the source.
void setLog2Decimation(unsigned int log2_decim)
virtual QString asJson() override
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
DeviceAPI * m_deviceAPI
BladeRF1InputSettings m_settings
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
bladerf_xb200_filter m_xb200Filter
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
virtual bool start()
virtual bool handleMessage(const Message &message)
virtual void destroy()
void setOriginatorIndex(qint32 originator_index)
SampleSinkFifo m_sampleFifo
bool setSize(int size)
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
QByteArray serialize() const
virtual bool deserialize(const QByteArray &data)
virtual const QString & getDeviceDescription() const
bladerf_xb200_path m_xb200Path
SWGBladeRF1InputSettings * getBladeRf1InputSettings()
QString m_deviceDescription
QNetworkRequest m_networkRequest
int getDeviceSetIndex() const
Definition: deviceapi.h:131
FileRecord * m_fileSink
File sink to record device I/Q output.
static MsgStartStop * create(bool startStop)
Definition: bladerf1input.h:89
virtual void setCenterFrequency(qint64 centerFrequency)
void * getBuddySharedPtr() const
Definition: deviceapi.h:161
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
Definition: message.h:52
void genUniqueFileName(uint deviceUID, int istream=-1)
Definition: filerecord.cpp:67
virtual int getSampleRate() const
Sample rate exposed by the source.
DSPDeviceSinkEngine * getDeviceSinkEngine()
Definition: deviceapi.h:154
virtual quint64 getCenterFrequency() const
Center frequency exposed by the source.
void setBuddySharedPtr(void *ptr)
Definition: deviceapi.h:162
virtual QByteArray serialize() const
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
void stopRecording()
Definition: filerecord.cpp:117
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
void setReverseApiPort(qint32 reverse_api_port)
static bool match(const Message *message)
Definition: message.cpp:45
struct bladerf * m_dev
void setCenterFrequency(qint64 center_frequency)
void removeAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Removes it.
Definition: deviceapi.cpp:100
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
virtual void stop()
virtual ~Bladerf1Input()
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const BladeRF1InputSettings &settings, bool force)
static MsgConfigureBladerf1 * create(const BladeRF1InputSettings &settings, bool force)
Definition: bladerf1input.h:48
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
const QString & getSamplingDeviceSerial() const
Definition: deviceapi.h:121
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
void webapiReverseSendStartStop(bool start)
QNetworkAccessManager * m_networkManager
void networkManagerFinished(QNetworkReply *reply)
struct bladerf * m_dev
device handle if the party has ownership else 0
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const BladeRF1InputSettings &settings)
bool deserialize(const QByteArray &data)
DeviceBladeRF1Params m_sharedParams
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int streamIndex=0)
Configure current device engine DSP corrections (Rx)
Definition: deviceapi.cpp:355
void setDirection(qint32 direction)
bool applySettings(const BladeRF1InputSettings &settings, bool force)
void setDeviceHwType(QString *device_hw_type)
Bladerf1InputThread * m_bladerfThread