26 #if (defined _WIN32_) || (defined _MSC_VER) 33 #include <boost/crc.hpp> 34 #include <boost/cstdint.hpp> 36 #include <QNetworkAccessManager> 37 #include <QNetworkReply> 60 m_deviceAPI(deviceAPI),
70 m_deviceSampleRate(48000),
73 m_dataAddress(
"127.0.0.1"),
106 double txDelayRatio = txDelay / 100.0;
107 int samplesPerBlock = RemoteNbBytesPerBlock /
sizeof(
Sample);
109 delay /= 128 + nbBlocksFEC;
111 qDebug() <<
"RemoteSink::setTxDelay:" 119 qDebug() <<
"RemoteSink::setNbBlocksFEC: nbBlocksFEC: " << nbBlocksFEC;
123 void RemoteSink::feed(
const SampleVector::const_iterator& begin,
const SampleVector::const_iterator& end,
bool firstOfBurst)
126 SampleVector::const_iterator it = begin;
130 int inSamplesIndex = it - begin;
131 int inRemainingSamples = end - it;
137 gettimeofday(&tv, 0);
143 metaData.m_nbOriginalBlocks = RemoteNbOrginalBlocks;
145 metaData.m_tv_sec = tv.tv_sec;
146 metaData.m_tv_usec = tv.tv_usec;
152 boost::crc_32_type
crc32;
154 metaData.m_crc32 = crc32.checksum();
163 *destMeta = metaData;
167 qDebug() <<
"RemoteSink::feed: meta: " 169 <<
":" << metaData.m_sampleRate
170 <<
":" << (int) (metaData.m_sampleBytes & 0xF)
171 <<
":" << (int) metaData.m_sampleBits
172 <<
"|" << (
int) metaData.m_nbOriginalBlocks
173 <<
":" << (int) metaData.m_nbFECBlocks
174 <<
"|" << metaData.m_tv_sec
175 <<
":" << metaData.m_tv_usec;
184 int samplesPerBlock = RemoteNbBytesPerBlock / (
SDR_RX_SAMP_SZ <= 16 ? 4 : 8);
188 (
const void *) &(*(begin+inSamplesIndex)),
189 inRemainingSamples *
sizeof(
Sample));
196 (
const void *) &(*(begin+inSamplesIndex)),
235 qDebug(
"RemoteSink::start");
248 Qt::QueuedConnection);
255 qDebug(
"RemoteSink::stop");
274 qDebug() <<
"RemoteSink::handleMessage: MsgChannelizerNotification:" 290 qDebug() <<
"RemoteSink::handleMessage: DSPSignalNotification:" 314 qDebug() <<
"RemoteSink::handleMessage: MsgConfigureRemoteSink";
325 qDebug() <<
"RemoteSink::handleMessage: MsgConfigureChannelizer:" 368 qDebug() <<
"RemoteSink::applySettings:" 373 <<
" force: " << force;
375 QList<QString> reverseAPIKeys;
379 reverseAPIKeys.append(
"nbFECBlocks");
386 reverseAPIKeys.append(
"txDelay");
392 reverseAPIKeys.append(
"dataAddress");
398 reverseAPIKeys.append(
"dataPort");
434 QString& errorMessage)
445 const QStringList& channelSettingsKeys,
447 QString& errorMessage)
452 if (channelSettingsKeys.contains(
"nbFECBlocks"))
456 if ((nbFECBlocks < 0) || (nbFECBlocks > 127)) {
463 if (channelSettingsKeys.contains(
"txDelay"))
474 if (channelSettingsKeys.contains(
"dataAddress")) {
478 if (channelSettingsKeys.contains(
"dataPort"))
482 if ((dataPort < 1024) || (dataPort > 65535)) {
489 if (channelSettingsKeys.contains(
"rgbColor")) {
492 if (channelSettingsKeys.contains(
"title")) {
495 if (channelSettingsKeys.contains(
"log2Decim")) {
499 if (channelSettingsKeys.contains(
"filterChainHash"))
505 if (channelSettingsKeys.contains(
"useReverseAPI")) {
508 if (channelSettingsKeys.contains(
"reverseAPIAddress")) {
511 if (channelSettingsKeys.contains(
"reverseAPIPort")) {
514 if (channelSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
517 if (channelSettingsKeys.contains(
"reverseAPIChannelIndex")) {
530 qDebug(
"RemoteSink::webapiSettingsPutPatch: forward to GUI: %p",
m_guiMessageQueue);
589 if (channelSettingsKeys.contains(
"nbFECBlocks") || force) {
592 if (channelSettingsKeys.contains(
"txDelay") || force)
596 if (channelSettingsKeys.contains(
"dataAddress") || force) {
599 if (channelSettingsKeys.contains(
"dataPort") || force) {
602 if (channelSettingsKeys.contains(
"rgbColor") || force) {
605 if (channelSettingsKeys.contains(
"title") || force) {
608 if (channelSettingsKeys.contains(
"log2Decim") || force) {
611 if (channelSettingsKeys.contains(
"filterChainHash") || force) {
615 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
621 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
623 QBuffer *buffer=
new QBuffer();
624 buffer->open((QBuffer::ReadWrite));
625 buffer->write(swgChannelSettings->
asJson().toUtf8());
631 delete swgChannelSettings;
636 QNetworkReply::NetworkError replyError = reply->error();
640 qWarning() <<
"RemoteSink::networkManagerFinished:" 641 <<
" error(" << (int) replyError
642 <<
"): " << replyError
643 <<
": " << reply->errorString();
647 QString answer = reply->readAll();
649 qDebug(
"RemoteSink::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
void networkManagerFinished(QNetworkReply *reply)
void setOriginatorChannelIndex(qint32 originator_channel_index)
void validateFilterChainHash(RemoteSinkSettings &settings)
QString * getReverseApiAddress()
void push(Message *message, bool emitSignal=true)
Push message onto queue.
uint16_t m_reverseAPIDeviceIndex
qint32 getReverseApiChannelIndex()
void removeChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
void addChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
qint32 getReverseApiPort()
qint32 getReverseApiDeviceIndex()
void setNbFecBlocks(qint32 nb_fec_blocks)
RemoteSuperBlock * m_superBlocks
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
uint32_t m_filterChainHash
bool deserialize(const QByteArray &data)
int getDeviceSetIndex() const
uint16_t m_frameCount
transmission frame count
int getSampleRate() const
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const RemoteSinkSettings &settings)
RemoteProtectedBlock m_protectedBlock
void setFilterChainHash(qint32 filter_chain_hash)
RemoteSinkThread * m_sinkThread
uint64_t m_centerFrequency
QNetworkAccessManager * m_networkManager
void setChannelType(QString *channel_type)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
void setDataAddress(QString *data_address)
QNetworkRequest m_networkRequest
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
int64_t m_frequencyOffset
RemoteMetaDataFEC m_currentMetaFEC
RemoteSinkSettings m_settings
void calculateFrequencyOffset()
DownChannelizer * m_channelizer
uint16_t m_reverseAPIChannelIndex
RemoteDataBlock * m_dataBlock
qint32 getFilterChainHash()
qint64 getCenterFrequency() const
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
uint32_t m_deviceSampleRate
ThreadedBasebandSampleSink * m_threadedChannelizer
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
static const QString m_channelIdURI
static const QString m_channelId
void setDataPort(qint32 data_port)
uint8_t buf[RemoteNbBytesPerBlock]
void applySettings(const RemoteSinkSettings &settings, bool force=false)
int m_txBlockIndex
Current index in blocks to transmit in the Tx row.
void set(MessageQueue *messageQueue, unsigned int log2Decim, unsigned int filterChainHash)
static bool match(const Message *message)
void setReverseApiPort(qint32 reverse_api_port)
void setLog2Decim(qint32 log2_decim)
void removeChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Remove a channel sink (Rx)
void setRgbColor(qint32 rgb_color)
void setDirection(qint32 direction)
void setSampleRate(uint32_t sampleRate)
virtual QString asJson() override
RemoteTxControlBlock m_txControlBlock
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool po)
QByteArray serialize() const
void addChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Add a channel sink (Rx)
void setTxDelay(qint32 tx_delay)
static MsgSampleRateNotification * create(int sampleRate)
virtual int webapiSettingsGet(SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
RemoteSink(DeviceAPI *deviceAPI)
int getSampleRate() const
void startStop(bool start)
void setRemoteSinkSettings(SWGRemoteSinkSettings *remote_sink_settings)
void dataBlockAvailable(RemoteDataBlock *dataBlock)
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
virtual QByteArray serialize() const
uint32_t crc32(const uint8_t *buf, int len)
QString m_reverseAPIAddress
RemoteSuperBlock m_superBlock
virtual int webapiSettingsPutPatch(bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
SWGRemoteSinkSettings * getRemoteSinkSettings()
int getIndexInDeviceSet() const
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
void setTitle(QString *title)
virtual bool deserialize(const QByteArray &data)
static double getShiftFactor(unsigned int log2, unsigned int chainHash)
int m_sampleIndex
Current sample index in protected block data.
qint64 getFrequencyOffset() const
uint16_t m_reverseAPIPort
QString * getDataAddress()
void setReverseApiAddress(QString *reverse_api_address)
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const RemoteSinkSettings &settings, bool force)
void setNbBlocksFEC(int nbBlocksFEC)
qint32 getUseReverseApi()
void setCenterFrequency(uint64_t centerFrequency)
void setTxDelay(int txDelay, int nbBlocksFEC)
void setUseReverseApi(qint32 use_reverse_api)
virtual bool handleMessage(const Message &cmd)
Processing of a message. Returns true if message has actually been processed.