23 #include <QNetworkReply> 46 m_deviceAPI(deviceAPI),
54 m_deviceAPI->setNbSinkStreams(1);
55 m_networkManager =
new QNetworkAccessManager();
56 connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(networkManagerFinished(QNetworkReply*)));
83 qDebug(
"BladeRF2Output::openDevice: look in Tx buddies");
88 if (deviceBladeRF2Shared == 0)
90 qCritical(
"BladeRF2Output::openDevice: the sink buddy shared pointer is null");
98 qCritical(
"BladeRF2Output::openDevice: cannot get device pointer from Tx buddy");
107 qDebug(
"BladeRF2Output::openDevice: look in Rx buddies");
112 if (deviceBladeRF2Shared == 0)
114 qCritical(
"BladeRF2Output::openDevice: the source buddy shared pointer is null");
122 qCritical(
"BladeRF2Output::openDevice: cannot get device pointer from Rx buddy");
131 qDebug(
"BladeRF2Output::openDevice: open device here");
139 qCritical(
"BladeRF2Output::openDevice: cannot open BladeRF2 device");
190 std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
192 for (; it != sinkBuddies.end(); ++it)
198 bladeRF2OutputThread = buddySink->
getThread();
200 if (bladeRF2OutputThread) {
206 return bladeRF2OutputThread;
217 std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
219 for (; it != sinkBuddies.end(); ++it)
264 qDebug(
"BladeRF2Output::start: no device object");
270 bool needsStart =
false;
272 if (bladeRF2OutputThread)
274 qDebug(
"BladeRF2Output::start: thread is already allocated");
276 int nbOriginalChannels = bladeRF2OutputThread->
getNbChannels();
278 if (requestedChannel+1 > nbOriginalChannels)
280 qDebug(
"BladeRF2Output::start: expand channels. Re-allocate thread and take ownership");
283 unsigned int *log2Interps =
new unsigned int[nbOriginalChannels];
285 for (
int i = 0;
i < nbOriginalChannels;
i++)
287 fifos[
i] = bladeRF2OutputThread->
getFifo(
i);
292 delete bladeRF2OutputThread;
296 for (
int i = 0;
i < nbOriginalChannels;
i++)
298 bladeRF2OutputThread->
setFifo(
i, fifos[
i]);
304 std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
306 for (; it != sinkBuddies.end(); ++it) {
317 delete[] log2Interps;
323 qDebug(
"BladeRF2Output::start: keep buddy thread");
328 qDebug(
"BladeRF2Output::start: allocate thread and take ownership");
341 qDebug(
"BladeRF2Output::start: enabling channel(s) and (re)starting the thread");
346 qCritical(
"BladeRF2Output::start: channel %u cannot be enabled",
i);
353 qDebug(
"BladeRF2Output::start: started");
383 if (bladeRF2OutputThread == 0) {
387 int nbOriginalChannels = bladeRF2OutputThread->
getNbChannels();
389 if (nbOriginalChannels == 1)
391 qDebug(
"BladeRF2Output::stop: SO mode. Just stop and delete the thread");
393 delete bladeRF2OutputThread;
398 std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
400 for (; it != sinkBuddies.end(); ++it) {
406 else if (requestedChannel == nbOriginalChannels - 1)
408 qDebug(
"BladeRF2Output::stop: MO mode. Reduce by deleting and re-creating the thread");
411 unsigned int *log2Interps =
new unsigned int[nbOriginalChannels-1];
412 bool stillActiveFIFO =
false;
414 for (
int i = 0;
i < nbOriginalChannels-1;
i++)
416 fifos[
i] = bladeRF2OutputThread->
getFifo(
i);
417 stillActiveFIFO = stillActiveFIFO || (bladeRF2OutputThread->
getFifo(
i) != 0);
421 delete bladeRF2OutputThread;
429 for (
int i = 0;
i < nbOriginalChannels-1;
i++)
431 bladeRF2OutputThread->
setFifo(
i, fifos[
i]);
437 qDebug(
"BladeRF2Output::stop: do not re-create thread as there are no more FIFOs active");
442 std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
444 for (; it != sinkBuddies.end(); ++it) {
449 for (
int i = nbOriginalChannels-1;
i >= 0;
i--) {
455 qDebug(
"BladeRF2Output::stop: enabling channel(s) and restarting the thread");
460 qCritical(
"BladeRF2Output::start: channel %u cannot be enabled",
i);
469 delete[] log2Interps;
473 qDebug(
"BladeRF2Output::stop: MO mode. Not changing MO configuration. Just remove FIFO reference");
474 bladeRF2OutputThread->
setFifo(requestedChannel, 0);
542 qint64 df = ((qint64)freq_hz * loPpmTenths) / 10000000LL;
545 int status = bladerf_set_frequency(dev, BLADERF_CHANNEL_TX(requestedChannel), freq_hz);
548 qWarning(
"BladeRF2Output::setDeviceCenterFrequency: bladerf_set_frequency(%lld) failed: %s",
549 freq_hz, bladerf_strerror(status));
554 qDebug(
"BladeRF2Output::setDeviceCenterFrequency: bladerf_set_frequency(%lld)", freq_hz);
592 qDebug() <<
"BladeRF2Output::handleMessage: MsgConfigureBladeRF2";
596 qDebug(
"BladeRF2Output::handleMessage: MsgConfigureBladeRF2 config error");
607 unsigned int tmp_uint;
633 status = bladerf_get_bandwidth(dev, BLADERF_CHANNEL_TX(requestedChannel), &tmp_uint);
636 qCritical(
"BladeRF2Output::handleMessage: MsgReportBuddyChange: bladerf_get_bandwidth error: %s", bladerf_strerror(status));
641 status = bladerf_get_bias_tee(dev, BLADERF_CHANNEL_TX(requestedChannel), &tmp_bool);
644 qCritical(
"BladeRF2Output::handleMessage: MsgReportBuddyChange: bladerf_get_bias_tee error: %s", bladerf_strerror(status));
673 qDebug() <<
"BladeRF2Input::handleMessage: MsgStartStop: " << (cmd.
getStartStop() ?
"start" :
"stop");
701 bool forwardChangeOwnDSP =
false;
702 bool forwardChangeRxBuddies =
false;
703 bool forwardChangeTxBuddies =
false;
704 QList<QString> reverseAPIKeys;
711 deviceCenterFrequency = deviceCenterFrequency < 0 ? 0 : deviceCenterFrequency;
715 reverseAPIKeys.append(
"devSampleRate");
719 if (bladeRF2OutputThread)
721 fifo = bladeRF2OutputThread->
getFifo(requestedChannel);
722 bladeRF2OutputThread->
setFifo(requestedChannel, 0);
747 forwardChangeOwnDSP =
true;
748 forwardChangeRxBuddies =
true;
749 forwardChangeTxBuddies =
true;
753 unsigned int actualSamplerate;
755 int status = bladerf_set_sample_rate(dev, BLADERF_CHANNEL_TX(requestedChannel),
761 qCritical(
"BladeRF2Output::applySettings: could not set sample rate: %d: %s",
766 qDebug() <<
"BladeRF2Output::applySettings: bladerf_set_sample_rate: actual sample rate is " << actualSamplerate;
773 reverseAPIKeys.append(
"bandwidth");
774 forwardChangeTxBuddies =
true;
778 unsigned int actualBandwidth;
779 int status = bladerf_set_bandwidth(dev, BLADERF_CHANNEL_TX(requestedChannel), settings.
m_bandwidth, &actualBandwidth);
783 qCritical(
"BladeRF2Output::applySettings: could not set bandwidth: %d: %s",
788 qDebug() <<
"BladeRF2Output::applySettings: bladerf_set_bandwidth: actual bandwidth is " << actualBandwidth;
795 reverseAPIKeys.append(
"log2Interp");
796 forwardChangeOwnDSP =
true;
799 if (outputThread != 0)
802 qDebug() <<
"BladeRF2Output::applySettings: set interpolation to " << (1<<settings.
m_log2Interp);
807 reverseAPIKeys.append(
"centerFrequency");
810 reverseAPIKeys.append(
"transverterMode");
813 reverseAPIKeys.append(
"transverterDeltaFrequency");
816 reverseAPIKeys.append(
"LOppmTenths");
825 forwardChangeOwnDSP =
true;
826 forwardChangeTxBuddies =
true;
845 reverseAPIKeys.append(
"biasTee");
846 forwardChangeTxBuddies =
true;
852 reverseAPIKeys.append(
"globalGain");
853 forwardChangeTxBuddies =
true;
858 int status = bladerf_set_gain(dev, BLADERF_CHANNEL_TX(requestedChannel), settings.
m_globalGain);
861 qWarning(
"BladeRF2Output::applySettings: bladerf_set_gain(%d) failed: %s",
864 qDebug(
"BladeRF2Output::applySettings: bladerf_set_gain(%d)", settings.
m_globalGain);
869 if (forwardChangeOwnDSP)
876 if (forwardChangeRxBuddies)
880 std::vector<DeviceAPI*>::const_iterator itSource = sourceBuddies.begin();
882 for (; itSource != sourceBuddies.end(); ++itSource)
890 (*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
894 if (forwardChangeTxBuddies)
898 std::vector<DeviceAPI*>::const_iterator itSink = sinkBuddies.begin();
900 for (; itSink != sinkBuddies.end(); ++itSink)
908 (*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
923 qDebug() <<
"BladeRF2Output::applySettings: " 926 <<
" deviceCenterFrequency: " << deviceCenterFrequency
932 <<
" nbChannels: " << nbChannels
943 if (bladeRF2OutputThread) {
952 QString& errorMessage)
963 const QStringList& deviceSettingsKeys,
965 QString& errorMessage)
970 if (deviceSettingsKeys.contains(
"centerFrequency")) {
973 if (deviceSettingsKeys.contains(
"LOppmTenths")) {
976 if (deviceSettingsKeys.contains(
"devSampleRate")) {
979 if (deviceSettingsKeys.contains(
"bandwidth")) {
982 if (deviceSettingsKeys.contains(
"log2Interp")) {
985 if (deviceSettingsKeys.contains(
"biasTee")) {
988 if (deviceSettingsKeys.contains(
"globalGain")) {
991 if (deviceSettingsKeys.contains(
"transverterDeltaFrequency")) {
994 if (deviceSettingsKeys.contains(
"transverterMode")) {
997 if (deviceSettingsKeys.contains(
"useReverseAPI")) {
1000 if (deviceSettingsKeys.contains(
"reverseAPIAddress")) {
1003 if (deviceSettingsKeys.contains(
"reverseAPIPort")) {
1006 if (deviceSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
1025 (void) errorMessage;
1097 QString& errorMessage)
1099 (void) errorMessage;
1107 QString& errorMessage)
1109 (void) errorMessage;
1134 if (deviceSettingsKeys.contains(
"centerFrequency") || force) {
1137 if (deviceSettingsKeys.contains(
"LOppmTenths") || force) {
1140 if (deviceSettingsKeys.contains(
"devSampleRate") || force) {
1143 if (deviceSettingsKeys.contains(
"bandwidth") || force) {
1146 if (deviceSettingsKeys.contains(
"log2Interp") || force) {
1149 if (deviceSettingsKeys.contains(
"biasTee") || force) {
1152 if (deviceSettingsKeys.contains(
"globalGain") || force) {
1155 if (deviceSettingsKeys.contains(
"transverterDeltaFrequency") || force) {
1158 if (deviceSettingsKeys.contains(
"transverterMode") || force) {
1162 QString deviceSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/device/settings")
1167 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
1169 QBuffer *buffer=
new QBuffer();
1170 buffer->open((QBuffer::ReadWrite));
1171 buffer->write(swgDeviceSettings->
asJson().toUtf8());
1177 delete swgDeviceSettings;
1187 QString deviceSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/device/run")
1192 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
1194 QBuffer *buffer=
new QBuffer();
1195 buffer->open((QBuffer::ReadWrite));
1196 buffer->write(swgDeviceSettings->
asJson().toUtf8());
1205 delete swgDeviceSettings;
1210 QNetworkReply::NetworkError replyError = reply->error();
1214 qWarning() <<
"BladeRF2Output::networkManagerFinished:" 1215 <<
" error(" << (int) replyError
1216 <<
"): " << replyError
1217 <<
": " << reply->errorString();
1221 QString answer = reply->readAll();
1223 qDebug(
"BladeRF2Output::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
QNetworkRequest m_networkRequest
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
void setLog2Interp(qint32 log2_interp)
qint64 getCenterFrequency()
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
SWGBladeRF2OutputSettings * getBladeRf2OutputSettings()
void setTransverterMode(qint32 transverter_mode)
void networkManagerFinished(QNetworkReply *reply)
uint16_t m_reverseAPIPort
void getGlobalGainRangeTx(int &min, int &max, int &step)
const std::vector< DeviceAPI * > & getSinkBuddies() const
static const float m_sampleFifoLengthInSeconds
virtual QString asJson() override
static const int m_sampleFifoMinSize
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
virtual const QString & getDeviceDescription() const
SampleSourceFifo * getFifo(unsigned int channel)
void setBandwidth(qint32 bandwidth)
BladeRF2OutputThread * m_thread
bool getStartStop() const
uint32_t getDeviceItemIndex() const
SWGFrequencyRange * getFrequencyRange()
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport &response)
void setStep(qint32 step)
void setDevSampleRate(qint32 dev_sample_rate)
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
unsigned int getLog2Interpolation(unsigned int channel) const
qint32 getReverseApiDeviceIndex()
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
void setBiasTee(qint32 bias_tee)
qint32 getUseReverseApi()
void setOriginatorIndex(qint32 originator_index)
void webapiReverseSendStartStop(bool start)
qint64 m_transverterDeltaFrequency
QByteArray serialize() const
virtual int getSampleRate() const
Sample rate exposed by the sink.
void getBandwidthRange(int &min, int &max, int &step)
bool setDeviceCenterFrequency(struct bladerf *dev, int requestedChannel, quint64 freq_hz, int loPpmTenths)
void setBiasTeeTx(bool enable)
MessageQueue m_inputMessageQueue
Input queue to the sink.
SWGRange * getBandwidthRange()
virtual int webapiReportGet(SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
unsigned int getNbChannels() const
int getDeviceSetIndex() const
static const int m_sampleFifoMinSize32
void * getBuddySharedPtr() const
void getBandwidthRangeTx(int &min, int &max, int &step)
void setFrequencyRange(SWGFrequencyRange *frequency_range)
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
virtual bool deserialize(const QByteArray &data)
void setReverseApiAddress(QString *reverse_api_address)
void getSampleRateRangeTx(int &min, int &max, int &step)
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
DeviceBladeRF2Shared m_deviceShared
qint32 getReverseApiPort()
void setBuddySharedPtr(void *ptr)
void setGlobalGain(qint32 global_gain)
uint16_t m_reverseAPIDeviceIndex
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
QString * getReverseApiAddress()
void setFifo(unsigned int channel, SampleSourceFifo *sampleFifo)
qint32 getDevSampleRate()
int getLOppmTenths() const
static bool match(const Message *message)
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
void setGlobalGainRange(SWGRange *global_gain_range)
void setLog2Interpolation(unsigned int channel, unsigned int log2_interp)
void setReverseApiPort(qint32 reverse_api_port)
SWGRange * getGlobalGainRange()
QString m_deviceDescription
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
static MsgReportBuddyChange * create(uint64_t centerFrequency, int LOppmTenths, int fcPos, int devSampleRate, bool rxElseTx)
void getFrequencyRangeTx(uint64_t &min, uint64_t &max, int &step)
static MsgStartStop * create(bool startStop)
void getDeviceEngineStateStr(QString &state)
void resize(uint32_t size)
const QString & getSamplingDeviceSerial() const
virtual QByteArray serialize() const
SWGBladeRF2OutputReport * getBladeRf2OutputReport()
void setLOppmTenths(qint32 l_oppm_tenths)
SWGRange * getSampleRateRange()
static MsgReportGainRange * create(int min, int max, int step)
BladeRF2OutputSettings m_settings
int m_channel
allocated channel (-1 if none)
bool open(const char *serial)
uint64_t getCenterFrequency() const
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const BladeRF2OutputSettings &settings)
void setStep(qint32 step)
virtual bool handleMessage(const Message &message)
void setBladeRf2OutputReport(SWGBladeRF2OutputReport *blade_rf2_output_report)
qint32 getTransverterMode()
void setThread(BladeRF2OutputThread *thread)
void setSampleRateRange(SWGRange *sample_rate_range)
void getGlobalGainRange(int &min, int &max, int &step)
SampleSourceFifo m_sampleSourceFifo
virtual void setCenterFrequency(qint64 centerFrequency)
const std::vector< DeviceAPI * > & getSourceBuddies() const
void setCenterFrequency(qint64 center_frequency)
void getFrequencyRange(uint64_t &min, uint64_t &max, int &step)
BladeRF2OutputThread * getThread()
int getDevSampleRate() const
void getSampleRateRange(int &min, int &max, int &step)
void setBandwidthRange(SWGRange *bandwidth_range)
virtual ~BladeRF2Output()
virtual quint64 getCenterFrequency() const
Center frequency exposed by the sink.
QString m_reverseAPIAddress
qint64 getTransverterDeltaFrequency()
MessageQueue * getMessageQueueToGUI()
QNetworkAccessManager * m_networkManager
quint64 m_centerFrequency
void setDirection(qint32 direction)
void setUseReverseApi(qint32 use_reverse_api)
void setTransverterDeltaFrequency(qint64 transverter_delta_frequency)
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const BladeRF2OutputSettings &settings, bool force)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void closeTx(int channel)
T max(const T &x, const T &y)
BladeRF2OutputThread * findThread()
bool deserialize(const QByteArray &data)
void setDeviceHwType(QString *device_hw_type)
bool applySettings(const BladeRF2OutputSettings &settings, bool force)
void setBladeRf2OutputSettings(SWGBladeRF2OutputSettings *blade_rf2_output_settings)
T min(const T &x, const T &y)
unsigned __int64 uint64_t