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