/* * 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" SoapyDummy::SoapyDummy( const SoapySDR::Kwargs &args ) : m_circ_buffer(1000000) { // On startup, initialise our epoch to current time, so that // it appears the counter just started counting using namespace std::chrono; const auto now = steady_clock::now(); m_time_epoch = duration_cast(now.time_since_epoch()).count(); } SoapyDummy::~SoapyDummy( void ) { } /******************************************************************* * Identification API ******************************************************************/ std::string SoapyDummy::getDriverKey( void ) const { return("Dummy"); } std::string SoapyDummy::getHardwareKey( void ) const { return "DummyHWKey"; } SoapySDR::Kwargs SoapyDummy::getHardwareInfo( void ) const { SoapySDR::Kwargs info; info["version"] = "1"; info["clock source"] = "fictious"; return info; } /******************************************************************* * Channels API ******************************************************************/ size_t SoapyDummy::getNumChannels( const int dir ) const { return 1; } bool SoapyDummy::getFullDuplex( const int direction, const size_t channel ) const { return true; } /******************************************************************* * Settings API ******************************************************************/ SoapySDR::ArgInfoList SoapyDummy::getSettingInfo(void) const { SoapySDR::ArgInfoList setArgs; /* example setting from hackrf SoapySDR::ArgInfo biastxArg; biastxArg.key="bias_tx"; biastxArg.value="false"; biastxArg.name="Antenna Bias"; biastxArg.description="Antenna port power control."; biastxArg.type=SoapySDR::ArgInfo::BOOL; setArgs.push_back(biastxArg); */ return setArgs; } void SoapyDummy::writeSetting(const std::string &key, const std::string &value) { /* if(key=="bias_tx"){ std::lock_guard lock(_device_mutex); _tx_stream.bias=(value=="true") ? true : false; int ret=hackrf_set_antenna_enable(_dev,_tx_stream.bias); if(ret!=HACKRF_SUCCESS){ SoapySDR_logf(SOAPY_SDR_INFO,"Failed to apply antenna bias voltage"); } } */ } std::string SoapyDummy::readSetting(const std::string &key) const { /* if (key == "bias_tx") { return _tx_stream.bias?"true":"false"; } */ return ""; } /******************************************************************* * Antenna API ******************************************************************/ std::vector SoapyDummy::listAntennas( const int direction, const size_t channel ) const { std::vector options; if ( direction == SOAPY_SDR_RX ) { options.push_back("RX"); } else { options.push_back("TX"); } return options; } void SoapyDummy::setAntenna( const int direction, const size_t channel, const std::string &name ) { /* TODO delete this function or throw if name != RX... */ } std::string SoapyDummy::getAntenna( const int direction, const size_t channel ) const { if ( direction == SOAPY_SDR_RX ) { return "RX"; } else { return "TX"; } } /******************************************************************* * Frontend corrections API ******************************************************************/ bool SoapyDummy::hasDCOffsetMode( const int direction, const size_t channel ) const { return false; } /******************************************************************* * Gain API ******************************************************************/ std::vector SoapyDummy::listGains( const int direction, const size_t channel ) const { std::vector options; options.push_back( "GAIN" ); return options; } void SoapyDummy::setGainMode( const int direction, const size_t channel, const bool automatic ) { /* enable AGC if the hardware supports it, or remove this function */ } bool SoapyDummy::getGainMode( const int direction, const size_t channel ) const { return false; } void SoapyDummy::setGain( const int direction, const size_t channel, const double value ) { if ( direction == SOAPY_SDR_RX ) { } else if ( direction == SOAPY_SDR_TX ) { } } void SoapyDummy::setGain( const int direction, const size_t channel, const std::string &name, const double value ) { } double SoapyDummy::getGain( const int direction, const size_t channel, const std::string &name ) const { return 10.0; } SoapySDR::Range SoapyDummy::getGainRange( const int direction, const size_t channel, const std::string &name ) const { if (name == "GAIN") { return(SoapySDR::Range( 0, 60 ) ); } return(SoapySDR::Range( 0, 0 ) ); } /******************************************************************* * Frequency API ******************************************************************/ void SoapyDummy::setFrequency( const int direction, const size_t channel, const std::string &name, const double frequency, const SoapySDR::Kwargs &args ) { if ( name != "RF" ) { throw std::runtime_error( "setFrequency(" + name + ") unknown name" ); } if (direction==SOAPY_SDR_RX){ m_frequency = frequency; } else if (direction==SOAPY_SDR_TX){ m_frequency = frequency; } } double SoapyDummy::getFrequency( const int direction, const size_t channel, const std::string &name ) const { if ( name != "RF" ) { throw std::runtime_error( "getFrequency(" + name + ") unknown name" ); } double freq = 0.0; if (direction==SOAPY_SDR_RX){ freq = m_frequency; } else if (direction==SOAPY_SDR_TX){ freq = m_frequency; } return freq; } SoapySDR::ArgInfoList SoapyDummy::getFrequencyArgsInfo(const int direction, const size_t channel) const { SoapySDR::ArgInfoList freqArgs; return freqArgs; } std::vector SoapyDummy::listFrequencies( const int direction, const size_t channel ) const { std::vector names; names.push_back( "RF" ); return names; } SoapySDR::RangeList SoapyDummy::getFrequencyRange( const int direction, const size_t channel, const std::string &name ) const { if ( name != "RF" ) throw std::runtime_error( "getFrequencyRange(" + name + ") unknown name" ); return(SoapySDR::RangeList( 1, SoapySDR::Range( 0, 7250000000ull ) ) ); } /******************************************************************* * Sample Rate API ******************************************************************/ void SoapyDummy::setSampleRate( const int direction, const size_t channel, const double rate ) { m_samplerate = rate; // ticks are in nanoseconds m_circ_buffer.set_ticks_per_sample(std::lrint(1e9 / rate)); } double SoapyDummy::getSampleRate( const int direction, const size_t channel ) const { return m_samplerate; } std::vector SoapyDummy::listSampleRates( const int direction, const size_t channel ) const { std::vector options; for ( double r = 1e6; r <= 20e6; r += 1e6 ) { options.push_back( r ); } return options; } void SoapyDummy::setBandwidth( const int direction, const size_t channel, const double bw ) { } double SoapyDummy::getBandwidth( const int direction, const size_t channel ) const { return 8000000; } std::vector SoapyDummy::listBandwidths( const int direction, const size_t channel ) const { std::vector options; options.push_back( 8000000 ); return(options); }