/* * The MIT License (MIT) * * Copyright (c) 2018 Matthias P. Braendli * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "SoapyDummy.hpp" #include #include #include #include #include std::vector SoapyDummy::getStreamFormats(const int direction, const size_t channel) const { std::vector formats; formats.push_back(SOAPY_SDR_CF32); return formats; } std::string SoapyDummy::getNativeStreamFormat(const int direction, const size_t channel, double &fullScale) const { fullScale = 1.0; return SOAPY_SDR_CF32; } SoapySDR::ArgInfoList SoapyDummy::getStreamArgsInfo(const int direction, const size_t channel) const { SoapySDR::ArgInfoList streamArgs; SoapySDR::ArgInfo buffersArg; buffersArg.key="buffers"; buffersArg.value = std::to_string(1); buffersArg.name = "Buffer Count"; buffersArg.description = "Number of buffers per read."; buffersArg.units = "buffers"; buffersArg.type = SoapySDR::ArgInfo::INT; streamArgs.push_back(buffersArg); return streamArgs; } SoapySDR::Stream* SoapyDummy::setupStream( const int direction, const std::string &format, const std::vector &channels, const SoapySDR::Kwargs &args ) { if (channels.size() > 1 or (channels.size() > 0 and channels.at(0) != 0 )) { throw std::runtime_error( "setupStream invalid channel selection" ); } if (direction==SOAPY_SDR_RX) { if (format == SOAPY_SDR_CF32) { SoapySDR_log( SOAPY_SDR_DEBUG, "Using format CF32." ); } else throw std::runtime_error( "setupStream invalid format " + format ); return RX_STREAM; } else if (direction==SOAPY_SDR_TX) { if (format == SOAPY_SDR_CF32) { SoapySDR_log( SOAPY_SDR_DEBUG, "Using format CF32." ); } else throw std::runtime_error( "setupStream invalid format " + format ); return TX_STREAM; } else { throw std::runtime_error("Invalid direction"); } } void SoapyDummy::closeStream( SoapySDR::Stream *stream ) { if (stream == RX_STREAM) { } else if (stream == TX_STREAM) { } } size_t SoapyDummy::getStreamMTU( SoapySDR::Stream *stream ) const { if (stream == RX_STREAM) { return m_rxstream.mtu; } else if (stream == TX_STREAM) { return m_txstream.mtu; } else { throw std::runtime_error("Invalid stream"); } } int SoapyDummy::activateStream( SoapySDR::Stream *stream, const int flags, const long long timeNs, const size_t numElems ) { if (stream == RX_STREAM) { SoapySDR_logf(SOAPY_SDR_DEBUG, "Start RX"); m_rxstream.active = true; } else if (stream == TX_STREAM) { SoapySDR_logf(SOAPY_SDR_DEBUG, "Start TX"); m_txstream.active = true; } return 0; } int SoapyDummy::deactivateStream( SoapySDR::Stream *stream, const int flags, const long long timeNs ) { if (stream == RX_STREAM) { m_rxstream.active = false; } else if (stream == TX_STREAM) { m_rxstream.active = false; } return 0; } int SoapyDummy::readStream( SoapySDR::Stream *stream, void * const *buffs, const size_t numElems, int &flags, long long &timeNs, const long timeoutUs ) { if (stream != RX_STREAM){ return SOAPY_SDR_NOT_SUPPORTED; } if (not m_rxstream.active) { using namespace std; this_thread::sleep_for(chrono::microseconds(timeoutUs)); return SOAPY_SDR_TIMEOUT; } std::complex * const buf = static_cast * const>(buffs[0]); size_t numToRead = std::min(numElems, this->getStreamMTU(stream)); const size_t numRead = m_circ_buffer.read(buf, numToRead); return numRead; } int SoapyDummy::writeStream( SoapySDR::Stream *stream, const void * const *buffs, const size_t numElems, int &flags, const long long timeNs, const long timeoutUs ) { if (stream != TX_STREAM){ return SOAPY_SDR_NOT_SUPPORTED; } if (not m_txstream.active) { using namespace std; this_thread::sleep_for(chrono::microseconds(timeoutUs)); return SOAPY_SDR_TIMEOUT; } const std::complex * const buf = static_cast * const>(buffs[0]); size_t numWritten = std::min(numElems, this->getStreamMTU(stream)); m_circ_buffer.write(buf, numWritten, timeNs); return numWritten; } int SoapyDummy::readStreamStatus( SoapySDR::Stream *stream, size_t &chanMask, int &flags, long long &timeNs, const long timeoutUs ){ if(stream != TX_STREAM){ return SOAPY_SDR_NOT_SUPPORTED; } return SOAPY_SDR_TIMEOUT; } size_t SoapyDummy::getNumDirectAccessBuffers( SoapySDR::Stream *stream) { return 0; }