diff --git a/lib/bladerf/bladerf_common.cc b/lib/bladerf/bladerf_common.cc index a68de17..b6e91d4 100644 --- a/lib/bladerf/bladerf_common.cc +++ b/lib/bladerf/bladerf_common.cc @@ -68,6 +68,11 @@ bladerf_common::~bladerf_common() bladerf_board_type bladerf_common::get_board_type(struct bladerf *dev) { + if (NULL == dev) { + throw std::runtime_error(std::string(__FUNCTION__) + ": " + + "null pointer caught: dev"); + } + std::string boardname = std::string(bladerf_get_board_name(dev)); if (boardname == "bladerf1") { @@ -91,7 +96,7 @@ bladerf_sptr bladerf_common::get_cached_device( struct bladerf_devinfo devinfo ) status = bladerf_get_devinfo(bladerf_sptr(dev).get(), &other_devinfo); if (status < 0) { - throw std::runtime_error(std::string(__FUNCTION__) + + throw std::runtime_error(std::string(__FUNCTION__) + ": " + "Failed to get devinfo for cached device: " + bladerf_strerror(status)); } @@ -505,9 +510,6 @@ void bladerf_common::init(dict_t &dict, bladerf_direction direction) _use_metadata = dict.count("enable_metadata") != 0; - _use_mimo = (dict.count("enable_mimo") != 0) && - (get_num_channels(direction) >= 2); - /* Require value to be >= 2 so we can ensure we have twice as many * buffers as transfers */ if (_num_buffers <= 1) { @@ -654,19 +656,6 @@ std::vector < std::string > bladerf_common::devices() return ret; } -size_t bladerf_common::get_num_channels(bladerf_direction direction) -{ - // TODO: Need to figure out how to deal with output_signature()->max_streams - // being stuck at 1 in source_impl.cc - return 1; - - // if (get_board_type(_dev.get()) == BLADERF_REV_2) { - // return 2; - // } - - // return 1; -} - double bladerf_common::set_sample_rate(bladerf_direction direction, double rate) { int status; diff --git a/lib/bladerf/bladerf_common.h b/lib/bladerf/bladerf_common.h index 3f366fa..629709a 100644 --- a/lib/bladerf/bladerf_common.h +++ b/lib/bladerf/bladerf_common.h @@ -67,7 +67,6 @@ protected: bool start(bladerf_direction direction); bool stop(bladerf_direction direction); - size_t get_num_channels(bladerf_direction direction); bladerf_board_type get_board_type(struct bladerf *dev); double set_sample_rate(bladerf_direction direction, double rate); diff --git a/lib/bladerf/bladerf_sink_c.cc b/lib/bladerf/bladerf_sink_c.cc index 5207eb1..377ed99 100644 --- a/lib/bladerf/bladerf_sink_c.cc +++ b/lib/bladerf/bladerf_sink_c.cc @@ -61,32 +61,38 @@ bladerf_sink_c_sptr make_bladerf_sink_c(const std::string &args) return gnuradio::get_initial_sptr(new bladerf_sink_c(args)); } -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept either - * 1 or 2 inputs. - */ -static const int MIN_IN = 1; // mininum number of input streams -static const int MAX_IN = 2; // maximum number of input streams -static const int MIN_OUT = 0; // minimum number of output streams -static const int MAX_OUT = 0; // maximum number of output streams - /* * The private constructor */ bladerf_sink_c::bladerf_sink_c(const std::string &args) :gr::sync_block("bladerf_sink_c", - gr::io_signature::make(MIN_IN, MAX_IN, sizeof(gr_complex)), - gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof(gr_complex))) + args_to_io_signature(args), + gr::io_signature::make(0, 0, 0)) { dict_t dict = params_to_dict(args); /* Perform src/sink agnostic initializations */ init(dict, BLADERF_TX); + + /* Bounds-checking input signature depending on our underlying hardware */ + size_t max_nchan = 1; + + if (get_board_type(_dev.get()) == BLADERF_REV_2) { + max_nchan = 2; + } + + if (get_num_channels() > max_nchan) { + std::cerr << _pfx + << "Warning: number of channels specified on command line (" + << get_num_channels() << ") is greater than the maximum number " + << "supported by this device (" << max_nchan << "). Resetting " + << "to " << max_nchan << "." + << std::endl; + + set_input_signature( gr::io_signature::make(max_nchan, max_nchan, sizeof(gr_complex) ) ); + } + + _use_mimo = get_num_channels() > 1; } bool bladerf_sink_c::start() @@ -289,7 +295,7 @@ std::vector < std::string > bladerf_sink_c::get_devices() size_t bladerf_sink_c::get_num_channels() { - return bladerf_common::get_num_channels(BLADERF_TX); + return input_signature()->max_streams(); } osmosdr::meta_range_t bladerf_sink_c::get_sample_rates() diff --git a/lib/bladerf/bladerf_source_c.cc b/lib/bladerf/bladerf_source_c.cc index 81a34f0..b0c1de9 100644 --- a/lib/bladerf/bladerf_source_c.cc +++ b/lib/bladerf/bladerf_source_c.cc @@ -53,27 +53,13 @@ bladerf_source_c_sptr make_bladerf_source_c(const std::string &args) return gnuradio::get_initial_sptr(new bladerf_source_c(args)); } -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept either - * 1 or 2 outputs. - */ -static const int MIN_IN = 0; // mininum number of input streams -static const int MAX_IN = 0; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 2; // maximum number of output streams - /* * The private constructor */ bladerf_source_c::bladerf_source_c(const std::string &args) :gr::sync_block("bladerf_source_c", - gr::io_signature::make(MIN_IN, MAX_IN, sizeof(gr_complex)), - gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof(gr_complex))) + gr::io_signature::make(0, 0, 0), + args_to_io_signature(args)) { int status; std::string device_name; @@ -125,6 +111,26 @@ bladerf_source_c::bladerf_source_c(const std::string &args) << "earlier FPGA version will result in misinterpeted samples." << std::endl; } + + /* Bounds-checking output signature depending on our underlying hardware */ + size_t max_nchan = 1; + + if (get_board_type(_dev.get()) == BLADERF_REV_2) { + max_nchan = 2; + } + + if (get_num_channels() > max_nchan) { + std::cerr << _pfx + << "Warning: number of channels specified on command line (" + << get_num_channels() << ") is greater than the maximum number " + << "supported by this device (" << max_nchan << "). Resetting " + << "to " << max_nchan << "." + << std::endl; + + set_output_signature( gr::io_signature::make(max_nchan, max_nchan, sizeof(gr_complex) ) ); + } + + _use_mimo = get_num_channels() > 1; } bool bladerf_source_c::start() @@ -199,7 +205,7 @@ std::vector < std::string > bladerf_source_c::get_devices() size_t bladerf_source_c::get_num_channels() { - return bladerf_common::get_num_channels(BLADERF_RX); + return output_signature()->max_streams(); } osmosdr::meta_range_t bladerf_source_c::get_sample_rates()