1 /* -*- c++ -*- */
2 /*
3  * Copyright 2010-2016 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "gr_uhd_common.h"
24 #include "usrp_source_impl.h"
25 #include <boost/format.hpp>
26 #include <boost/make_shared.hpp>
27 #include <boost/thread/thread.hpp>
28 #include <iostream>
29 #include <stdexcept>
30 
31 namespace gr {
32 namespace uhd {
33 
34 
make(const::uhd::device_addr_t & device_addr,const::uhd::stream_args_t & stream_args,const bool issue_stream_cmd_on_start)35 usrp_source::sptr usrp_source::make(const ::uhd::device_addr_t& device_addr,
36                                     const ::uhd::stream_args_t& stream_args,
37                                     const bool issue_stream_cmd_on_start)
38 {
39     check_abi();
40     return usrp_source::sptr(new usrp_source_impl(
41         device_addr, stream_args_ensure(stream_args), issue_stream_cmd_on_start));
42 }
43 
usrp_source_impl(const::uhd::device_addr_t & device_addr,const::uhd::stream_args_t & stream_args,const bool issue_stream_cmd_on_start)44 usrp_source_impl::usrp_source_impl(const ::uhd::device_addr_t& device_addr,
45                                    const ::uhd::stream_args_t& stream_args,
46                                    const bool issue_stream_cmd_on_start)
47     : usrp_block("usrp_source", io_signature::make(0, 0, 0), args_to_io_sig(stream_args)),
48       usrp_block_impl(device_addr, stream_args, ""),
49       _recv_timeout(0.1), // seconds
50       _recv_one_packet(true),
51       _tag_now(false),
52       _issue_stream_cmd_on_start(issue_stream_cmd_on_start)
53 {
54     std::stringstream str;
55     str << name() << unique_id();
56     _id = pmt::string_to_symbol(str.str());
57 
58     _samp_rate = this->get_samp_rate();
59     _samps_per_packet = 1;
60     register_msg_cmd_handler(cmd_tag_key(),
61                              [this](const pmt::pmt_t& tag, const int, const pmt::pmt_t&) {
62                                  this->_cmd_handler_tag(tag);
63                              });
64 }
65 
~usrp_source_impl()66 usrp_source_impl::~usrp_source_impl() {}
67 
get_usrp_info(size_t chan)68 ::uhd::dict<std::string, std::string> usrp_source_impl::get_usrp_info(size_t chan)
69 {
70     chan = _stream_args.channels[chan];
71     return _dev->get_usrp_rx_info(chan);
72 }
73 
set_subdev_spec(const std::string & spec,size_t mboard)74 void usrp_source_impl::set_subdev_spec(const std::string& spec, size_t mboard)
75 {
76     return _dev->set_rx_subdev_spec(spec, mboard);
77 }
78 
get_subdev_spec(size_t mboard)79 std::string usrp_source_impl::get_subdev_spec(size_t mboard)
80 {
81     return _dev->get_rx_subdev_spec(mboard).to_string();
82 }
83 
set_samp_rate(double rate)84 void usrp_source_impl::set_samp_rate(double rate)
85 {
86     BOOST_FOREACH (const size_t chan, _stream_args.channels) {
87         _dev->set_rx_rate(rate, chan);
88     }
89     _samp_rate = this->get_samp_rate();
90     _tag_now = true;
91 }
92 
get_samp_rate(void)93 double usrp_source_impl::get_samp_rate(void)
94 {
95     return _dev->get_rx_rate(_stream_args.channels[0]);
96 }
97 
get_samp_rates(void)98 ::uhd::meta_range_t usrp_source_impl::get_samp_rates(void)
99 {
100     return _dev->get_rx_rates(_stream_args.channels[0]);
101 }
102 
103 ::uhd::tune_result_t
set_center_freq(const::uhd::tune_request_t tune_request,size_t chan)104 usrp_source_impl::set_center_freq(const ::uhd::tune_request_t tune_request, size_t chan)
105 {
106     chan = _stream_args.channels[chan];
107     const ::uhd::tune_result_t res = _dev->set_rx_freq(tune_request, chan);
108     _tag_now = true;
109     return res;
110 }
111 
112 ::uhd::tune_result_t
_set_center_freq_from_internals(size_t chan,pmt::pmt_t direction)113 usrp_source_impl::_set_center_freq_from_internals(size_t chan, pmt::pmt_t direction)
114 {
115     _chans_to_tune.reset(chan);
116     if (pmt::eqv(direction, ant_direction_tx())) {
117         // TODO: what happens if the TX device is not instantiated? Catch error?
118         return _dev->set_tx_freq(_curr_tune_req[chan], _stream_args.channels[chan]);
119     } else {
120         return set_center_freq(_curr_tune_req[chan], chan);
121     }
122 }
123 
get_center_freq(size_t chan)124 double usrp_source_impl::get_center_freq(size_t chan)
125 {
126     chan = _stream_args.channels[chan];
127     return _dev->get_rx_freq(chan);
128 }
129 
get_freq_range(size_t chan)130 ::uhd::freq_range_t usrp_source_impl::get_freq_range(size_t chan)
131 {
132     chan = _stream_args.channels[chan];
133     return _dev->get_rx_freq_range(chan);
134 }
135 
set_gain(double gain,size_t chan)136 void usrp_source_impl::set_gain(double gain, size_t chan)
137 {
138     chan = _stream_args.channels[chan];
139     return _dev->set_rx_gain(gain, chan);
140 }
141 
set_gain(double gain,const std::string & name,size_t chan)142 void usrp_source_impl::set_gain(double gain, const std::string& name, size_t chan)
143 {
144     chan = _stream_args.channels[chan];
145     return _dev->set_rx_gain(gain, name, chan);
146 }
147 
set_rx_agc(const bool enable,size_t chan)148 void usrp_source_impl::set_rx_agc(const bool enable, size_t chan)
149 {
150 #if UHD_VERSION >= 30803
151     chan = _stream_args.channels[chan];
152     return _dev->set_rx_agc(enable, chan);
153 #else
154     throw std::runtime_error("not implemented in this version");
155 #endif
156 }
157 
set_normalized_gain(double norm_gain,size_t chan)158 void usrp_source_impl::set_normalized_gain(double norm_gain, size_t chan)
159 {
160 #ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN
161     _dev->set_normalized_rx_gain(norm_gain, chan);
162 #else
163     if (norm_gain > 1.0 || norm_gain < 0.0) {
164         throw std::runtime_error("Normalized gain out of range, must be in [0, 1].");
165     }
166     ::uhd::gain_range_t gain_range = get_gain_range(chan);
167     double abs_gain =
168         (norm_gain * (gain_range.stop() - gain_range.start())) + gain_range.start();
169     set_gain(abs_gain, chan);
170 #endif
171 }
172 
get_gain(size_t chan)173 double usrp_source_impl::get_gain(size_t chan)
174 {
175     chan = _stream_args.channels[chan];
176     return _dev->get_rx_gain(chan);
177 }
178 
get_gain(const std::string & name,size_t chan)179 double usrp_source_impl::get_gain(const std::string& name, size_t chan)
180 {
181     chan = _stream_args.channels[chan];
182     return _dev->get_rx_gain(name, chan);
183 }
184 
get_normalized_gain(size_t chan)185 double usrp_source_impl::get_normalized_gain(size_t chan)
186 {
187 #ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN
188     return _dev->get_normalized_rx_gain(chan);
189 #else
190     ::uhd::gain_range_t gain_range = get_gain_range(chan);
191     double norm_gain =
192         (get_gain(chan) - gain_range.start()) / (gain_range.stop() - gain_range.start());
193     // Avoid rounding errors:
194     if (norm_gain > 1.0)
195         return 1.0;
196     if (norm_gain < 0.0)
197         return 0.0;
198     return norm_gain;
199 #endif
200 }
201 
get_gain_names(size_t chan)202 std::vector<std::string> usrp_source_impl::get_gain_names(size_t chan)
203 {
204     chan = _stream_args.channels[chan];
205     return _dev->get_rx_gain_names(chan);
206 }
207 
get_gain_range(size_t chan)208 ::uhd::gain_range_t usrp_source_impl::get_gain_range(size_t chan)
209 {
210     chan = _stream_args.channels[chan];
211     return _dev->get_rx_gain_range(chan);
212 }
213 
get_gain_range(const std::string & name,size_t chan)214 ::uhd::gain_range_t usrp_source_impl::get_gain_range(const std::string& name, size_t chan)
215 {
216     chan = _stream_args.channels[chan];
217     return _dev->get_rx_gain_range(name, chan);
218 }
219 
set_antenna(const std::string & ant,size_t chan)220 void usrp_source_impl::set_antenna(const std::string& ant, size_t chan)
221 {
222     chan = _stream_args.channels[chan];
223     return _dev->set_rx_antenna(ant, chan);
224 }
225 
get_antenna(size_t chan)226 std::string usrp_source_impl::get_antenna(size_t chan)
227 {
228     chan = _stream_args.channels[chan];
229     return _dev->get_rx_antenna(chan);
230 }
231 
get_antennas(size_t chan)232 std::vector<std::string> usrp_source_impl::get_antennas(size_t chan)
233 {
234     chan = _stream_args.channels[chan];
235     return _dev->get_rx_antennas(chan);
236 }
237 
set_bandwidth(double bandwidth,size_t chan)238 void usrp_source_impl::set_bandwidth(double bandwidth, size_t chan)
239 {
240     chan = _stream_args.channels[chan];
241     return _dev->set_rx_bandwidth(bandwidth, chan);
242 }
243 
get_bandwidth(size_t chan)244 double usrp_source_impl::get_bandwidth(size_t chan)
245 {
246     chan = _stream_args.channels[chan];
247     return _dev->get_rx_bandwidth(chan);
248 }
249 
get_bandwidth_range(size_t chan)250 ::uhd::freq_range_t usrp_source_impl::get_bandwidth_range(size_t chan)
251 {
252     chan = _stream_args.channels[chan];
253     return _dev->get_rx_bandwidth_range(chan);
254 }
255 
get_lo_names(size_t chan)256 std::vector<std::string> usrp_source_impl::get_lo_names(size_t chan)
257 {
258 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
259     chan = _stream_args.channels[chan];
260     return _dev->get_rx_lo_names(chan);
261 #else
262     throw std::runtime_error("not implemented in this version");
263 #endif
264 }
265 
get_lo_source(const std::string & name,size_t chan)266 const std::string usrp_source_impl::get_lo_source(const std::string& name, size_t chan)
267 {
268 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
269     chan = _stream_args.channels[chan];
270     return _dev->get_rx_lo_source(name, chan);
271 #else
272     throw std::runtime_error("not implemented in this version");
273 #endif
274 }
275 
get_lo_sources(const std::string & name,size_t chan)276 std::vector<std::string> usrp_source_impl::get_lo_sources(const std::string& name,
277                                                           size_t chan)
278 {
279 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
280     chan = _stream_args.channels[chan];
281     return _dev->get_rx_lo_sources(name, chan);
282 #else
283     throw std::runtime_error("not implemented in this version");
284 #endif
285 }
286 
set_lo_source(const std::string & src,const std::string & name,size_t chan)287 void usrp_source_impl::set_lo_source(const std::string& src,
288                                      const std::string& name,
289                                      size_t chan)
290 {
291 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
292     chan = _stream_args.channels[chan];
293     return _dev->set_rx_lo_source(src, name, chan);
294 #else
295     throw std::runtime_error("not implemented in this version");
296 #endif
297 }
298 
get_lo_export_enabled(const std::string & name,size_t chan)299 bool usrp_source_impl::get_lo_export_enabled(const std::string& name, size_t chan)
300 {
301 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
302     chan = _stream_args.channels[chan];
303     return _dev->get_rx_lo_export_enabled(name, chan);
304 #else
305     throw std::runtime_error("not implemented in this version");
306 #endif
307 }
308 
set_lo_export_enabled(bool enabled,const std::string & name,size_t chan)309 void usrp_source_impl::set_lo_export_enabled(bool enabled,
310                                              const std::string& name,
311                                              size_t chan)
312 {
313 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
314     chan = _stream_args.channels[chan];
315     return _dev->set_rx_lo_export_enabled(enabled, name, chan);
316 #else
317     throw std::runtime_error("not implemented in this version");
318 #endif
319 }
320 
get_lo_freq_range(const std::string & name,size_t chan)321 ::uhd::freq_range_t usrp_source_impl::get_lo_freq_range(const std::string& name,
322                                                         size_t chan)
323 {
324 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
325     chan = _stream_args.channels[chan];
326     return _dev->get_rx_lo_freq_range(name, chan);
327 #else
328     throw std::runtime_error("not implemented in this version");
329 #endif
330 }
331 
get_lo_freq(const std::string & name,size_t chan)332 double usrp_source_impl::get_lo_freq(const std::string& name, size_t chan)
333 {
334 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
335     chan = _stream_args.channels[chan];
336     return _dev->get_rx_lo_freq(name, chan);
337 #else
338     throw std::runtime_error("not implemented in this version");
339 #endif
340 }
341 
set_lo_freq(double freq,const std::string & name,size_t chan)342 double usrp_source_impl::set_lo_freq(double freq, const std::string& name, size_t chan)
343 {
344 #ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
345     chan = _stream_args.channels[chan];
346     return _dev->set_rx_lo_freq(freq, name, chan);
347 #else
348     throw std::runtime_error("not implemented in this version");
349 #endif
350 }
351 
set_auto_dc_offset(const bool enable,size_t chan)352 void usrp_source_impl::set_auto_dc_offset(const bool enable, size_t chan)
353 {
354     chan = _stream_args.channels[chan];
355     return _dev->set_rx_dc_offset(enable, chan);
356 }
357 
set_dc_offset(const std::complex<double> & offset,size_t chan)358 void usrp_source_impl::set_dc_offset(const std::complex<double>& offset, size_t chan)
359 {
360     chan = _stream_args.channels[chan];
361     return _dev->set_rx_dc_offset(offset, chan);
362 }
363 
set_auto_iq_balance(const bool enable,size_t chan)364 void usrp_source_impl::set_auto_iq_balance(const bool enable, size_t chan)
365 {
366     chan = _stream_args.channels[chan];
367 #ifdef UHD_USRP_MULTI_USRP_FRONTEND_IQ_AUTO_API
368     return _dev->set_rx_iq_balance(enable, chan);
369 #else
370     throw std::runtime_error("not implemented in this version");
371 #endif
372 }
373 
374 
set_iq_balance(const std::complex<double> & correction,size_t chan)375 void usrp_source_impl::set_iq_balance(const std::complex<double>& correction, size_t chan)
376 {
377     chan = _stream_args.channels[chan];
378     return _dev->set_rx_iq_balance(correction, chan);
379 }
380 
get_sensor(const std::string & name,size_t chan)381 ::uhd::sensor_value_t usrp_source_impl::get_sensor(const std::string& name, size_t chan)
382 {
383     chan = _stream_args.channels[chan];
384     return _dev->get_rx_sensor(name, chan);
385 }
386 
get_sensor_names(size_t chan)387 std::vector<std::string> usrp_source_impl::get_sensor_names(size_t chan)
388 {
389     chan = _stream_args.channels[chan];
390     return _dev->get_rx_sensor_names(chan);
391 }
392 
get_dboard_iface(size_t chan)393 ::uhd::usrp::dboard_iface::sptr usrp_source_impl::get_dboard_iface(size_t chan)
394 {
395     chan = _stream_args.channels[chan];
396     return _dev->get_rx_dboard_iface(chan);
397 }
398 
set_stream_args(const::uhd::stream_args_t & stream_args)399 void usrp_source_impl::set_stream_args(const ::uhd::stream_args_t& stream_args)
400 {
401     _update_stream_args(stream_args);
402     if (_rx_stream) {
403         _rx_stream.reset();
404     }
405 }
406 
_cmd_handler_tag(const pmt::pmt_t & tag)407 void usrp_source_impl::_cmd_handler_tag(const pmt::pmt_t& tag) { _tag_now = true; }
408 
set_start_time(const::uhd::time_spec_t & time)409 void usrp_source_impl::set_start_time(const ::uhd::time_spec_t& time)
410 {
411     _start_time = time;
412     _start_time_set = true;
413     _stream_now = false;
414 }
415 
issue_stream_cmd(const::uhd::stream_cmd_t & cmd)416 void usrp_source_impl::issue_stream_cmd(const ::uhd::stream_cmd_t& cmd)
417 {
418 // This is a new define in UHD 3.6 which is used to separate 3.6 and pre 3.6
419 #ifdef INCLUDED_UHD_UTILS_MSG_TASK_HPP
420     _rx_stream->issue_stream_cmd(cmd);
421 #else
422     for (size_t i = 0; i < _stream_args.channels.size(); i++) {
423         _dev->issue_stream_cmd(cmd, _stream_args.channels[i]);
424     }
425 #endif
426     _tag_now = true;
427 }
428 
set_recv_timeout(const double timeout,const bool one_packet)429 void usrp_source_impl::set_recv_timeout(const double timeout, const bool one_packet)
430 {
431     _recv_timeout = timeout;
432     _recv_one_packet = one_packet;
433 }
434 
start(void)435 bool usrp_source_impl::start(void)
436 {
437     boost::recursive_mutex::scoped_lock lock(d_mutex);
438     if (not _rx_stream) {
439         _rx_stream = _dev->get_rx_stream(_stream_args);
440         _samps_per_packet = _rx_stream->get_max_num_samps();
441     }
442     if (_issue_stream_cmd_on_start) {
443         // setup a stream command that starts streaming slightly in the future
444         static const double reasonable_delay = 0.1; // order of magnitude over RTT
445         ::uhd::stream_cmd_t stream_cmd(::uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
446         stream_cmd.stream_now = _stream_now;
447         if (_start_time_set) {
448             _start_time_set = false; // cleared for next run
449             stream_cmd.time_spec = _start_time;
450         } else {
451             stream_cmd.time_spec = get_time_now() + ::uhd::time_spec_t(reasonable_delay);
452         }
453         this->issue_stream_cmd(stream_cmd);
454     }
455     _tag_now = true;
456     return true;
457 }
458 
flush(void)459 void usrp_source_impl::flush(void)
460 {
461     const size_t nbytes = 4096;
462     gr_vector_void_star outputs;
463     std::vector<std::vector<char>> buffs(_nchan, std::vector<char>(nbytes));
464     for (size_t i = 0; i < _nchan; i++) {
465         outputs.push_back(&buffs[i].front());
466     }
467     while (true) {
468         const size_t bpi = ::uhd::convert::get_bytes_per_item(_stream_args.cpu_format);
469         if (_rx_stream)
470             // get the remaining samples out of the buffers
471             _rx_stream->recv(outputs, nbytes / bpi, _metadata, 0.0);
472         else
473             // no rx streamer -- nothing to flush
474             break;
475 
476         if (_metadata.error_code == ::uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
477             break;
478     }
479 }
480 
stop(void)481 bool usrp_source_impl::stop(void)
482 {
483     boost::recursive_mutex::scoped_lock lock(d_mutex);
484     this->issue_stream_cmd(::uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
485     this->flush();
486 
487     return true;
488 }
489 
finite_acquisition(const size_t nsamps)490 std::vector<std::complex<float>> usrp_source_impl::finite_acquisition(const size_t nsamps)
491 {
492     if (_nchan != 1)
493         throw std::runtime_error("finite_acquisition: usrp source has multiple channels, "
494                                  "call finite_acquisition_v");
495     return finite_acquisition_v(nsamps).front();
496 }
497 
498 std::vector<std::vector<std::complex<float>>>
finite_acquisition_v(const size_t nsamps)499 usrp_source_impl::finite_acquisition_v(const size_t nsamps)
500 {
501     // kludgy way to ensure rx streamer exists
502     if (!_rx_stream) {
503         this->start();
504         this->stop();
505     }
506 
507     // flush so there is no queued-up data
508     this->flush();
509 
510     // create a multi-dimensional container to hold an array of sample buffers
511     std::vector<std::vector<std::complex<float>>> samps(
512         _nchan, std::vector<std::complex<float>>(nsamps));
513 
514     // load the void* vector of buffer pointers
515     std::vector<void*> buffs(_nchan);
516     for (size_t i = 0; i < _nchan; i++) {
517         buffs[i] = &samps[i].front();
518     }
519 
520     // tell the device to stream a finite amount
521     ::uhd::stream_cmd_t cmd(::uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
522     cmd.num_samps = nsamps;
523     cmd.stream_now = _stream_now;
524     static const double reasonable_delay = 0.1; // order of magnitude over RTT
525     cmd.time_spec = get_time_now() + ::uhd::time_spec_t(reasonable_delay);
526     this->issue_stream_cmd(cmd);
527 
528     // receive samples until timeout
529     const size_t actual_num_samps = _rx_stream->recv(buffs, nsamps, _metadata, 1.0);
530 
531     // resize the resulting sample buffers
532     for (size_t i = 0; i < _nchan; i++) {
533         samps[i].resize(actual_num_samps);
534     }
535 
536     return samps;
537 }
538 
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)539 int usrp_source_impl::work(int noutput_items,
540                            gr_vector_const_void_star& input_items,
541                            gr_vector_void_star& output_items)
542 {
543     boost::recursive_mutex::scoped_lock lock(d_mutex);
544     boost::this_thread::disable_interruption disable_interrupt;
545     // In order to allow for low-latency:
546     // We receive all available packets without timeout.
547     // This call can timeout under regular operation...
548     size_t num_samps = _rx_stream->recv(
549         output_items, noutput_items, _metadata, _recv_timeout, _recv_one_packet);
550     boost::this_thread::restore_interruption restore_interrupt(disable_interrupt);
551 
552     // handle possible errors conditions
553     switch (_metadata.error_code) {
554     case ::uhd::rx_metadata_t::ERROR_CODE_NONE:
555         if (_tag_now) {
556             _tag_now = false;
557             // create a timestamp pmt for the first sample
558             const pmt::pmt_t val =
559                 pmt::make_tuple(pmt::from_uint64(_metadata.time_spec.get_full_secs()),
560                                 pmt::from_double(_metadata.time_spec.get_frac_secs()));
561             // create a tag set for each channel
562             for (size_t i = 0; i < _nchan; i++) {
563                 this->add_item_tag(i, nitems_written(0), TIME_KEY, val, _id);
564                 this->add_item_tag(
565                     i, nitems_written(0), RATE_KEY, pmt::from_double(_samp_rate), _id);
566                 this->add_item_tag(i,
567                                    nitems_written(0),
568                                    FREQ_KEY,
569                                    pmt::from_double(this->get_center_freq(i)),
570                                    _id);
571             }
572         }
573         break;
574 
575     case ::uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
576         // its ok to timeout, perhaps the user is doing finite streaming
577         return 0;
578 
579     case ::uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
580         _tag_now = true;
581         // ignore overflows and try work again
582         return work(noutput_items, input_items, output_items);
583 
584     default:
585         // GR_LOG_WARN(d_logger, boost::format("USRP Source Block caught rx error: %d") %
586         // _metadata.strerror());
587         GR_LOG_WARN(d_logger,
588                     boost::format("USRP Source Block caught rx error code: %d") %
589                         _metadata.error_code);
590         return num_samps;
591     }
592 
593     return num_samps;
594 }
595 
setup_rpc()596 void usrp_source_impl::setup_rpc()
597 {
598 #ifdef GR_CTRLPORT
599     add_rpc_variable(rpcbasic_sptr(new rpcbasic_register_handler<usrp_block>(
600         alias(), "command", "", "UHD Commands", RPC_PRIVLVL_MIN, DISPNULL)));
601 #endif /* GR_CTRLPORT */
602 }
603 
604 } /* namespace uhd */
605 } /* namespace gr */
606