void flush_recv(uhd::rx_streamer::sptr rx_stream){ std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); uhd::rx_metadata_t md; do{ rx_stream->recv(&buff.front(), buff.size(), md); } while (md.error_code != uhd::rx_metadata_t::ERROR_CODE_TIMEOUT); }
/*********************************************************************** * RX Hammer **********************************************************************/ void rx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_cpu, uhd::rx_streamer::sptr rx_stream){ uhd::set_thread_priority_safe(); //print pre-test summary std::cout << boost::format( "Testing receive rate %f Msps" ) % (usrp->get_rx_rate()/1e6) << std::endl; //setup variables and allocate buffer uhd::rx_metadata_t md; const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(rx_cpu)); std::vector<void *> buffs; for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) buffs.push_back(&buff.front()); //same buffer for each channel bool had_an_overflow = false; uhd::time_spec_t last_time; const double rate = usrp->get_rx_rate(); double timeout = 1; uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); cmd.stream_now = (buffs.size() == 1); srand( time(NULL) ); while (not boost::this_thread::interruption_requested()){ cmd.num_samps = rand() % 100000; rx_stream->issue_stream_cmd(cmd); num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, timeout, true); //handle the error codes switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_NONE: if (had_an_overflow){ had_an_overflow = false; num_dropped_samps += boost::math::iround((md.time_spec - last_time).get_real_secs()*rate); } break; case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: had_an_overflow = true; last_time = md.time_spec; if (!md.out_of_sequence) num_overflows++; break; default: std::cerr << "Receiver error: " << md.strerror() << std::endl; std::cerr << "Unexpected error on recv, continuing..." << std::endl; break; } } }
/*********************************************************************** * Data capture routine **********************************************************************/ static void capture_samples( uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, std::vector<samp_type > &buff, const size_t nsamps_requested) { buff.resize(nsamps_requested); uhd::rx_metadata_t md; // Right after the stream is started, there will be transient data. // That transient data is discarded and only "good" samples are returned. size_t nsamps_to_discard = size_t(usrp->get_rx_rate() * 0.001); // 1ms to be discarded std::vector<samp_type> discard_buff(nsamps_to_discard); uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = buff.size() + nsamps_to_discard; stream_cmd.stream_now = true; usrp->issue_stream_cmd(stream_cmd); size_t num_rx_samps = 0; // Discard the transient samples. rx_stream->recv(&discard_buff.front(), discard_buff.size(), md); if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { throw std::runtime_error(str(boost::format( "Receiver error: %s" ) % md.strerror())); } // Now capture the data we want num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); //validate the received data if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { throw std::runtime_error(str(boost::format( "Receiver error: %s" ) % md.strerror())); } //we can live if all the data didnt come in if (num_rx_samps > buff.size()/2) { buff.resize(num_rx_samps); return; } if (num_rx_samps != buff.size()) throw std::runtime_error("did not get all the samples requested"); }
bool uhd_device::flush_recv(size_t num_pkts) { uhd::rx_metadata_t md; size_t num_smpls; uint32_t buff[rx_spp]; float timeout; // Use .01 sec instead of the default .1 sec timeout = .01; for (size_t i = 0; i < num_pkts; i++) { num_smpls = rx_stream->recv(buff, rx_spp, md, timeout, true); if (!num_smpls) { switch (md.error_code) { case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: return true; default: continue; } } } return true; }
/*********************************************************************** * Data capture routine **********************************************************************/ static void capture_samples( uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, std::vector<samp_type > &buff, const size_t nsamps_requested ){ buff.resize(nsamps_requested); uhd::rx_metadata_t md; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = buff.size(); stream_cmd.stream_now = true; usrp->issue_stream_cmd(stream_cmd); const size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); //validate the received data if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ throw std::runtime_error(str(boost::format( "Receiver error: %s" ) % md.strerror())); } //we can live if all the data didnt come in if (num_rx_samps > buff.size()/2){ buff.resize(num_rx_samps); return; } if (num_rx_samps != buff.size()){ throw std::runtime_error("did not get all the samples requested"); } }
/*! * Test the broken chain message: * Issue a stream command with num samps and more. * We expect to get an inline broken chain message. */ bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ std::cout << "Test broken chain message... " << std::flush; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE); stream_cmd.stream_now = true; stream_cmd.num_samps = rx_stream->get_max_num_samps(); rx_stream->issue_stream_cmd(stream_cmd); std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); uhd::rx_metadata_t md; rx_stream->recv( //once for the requested samples &buff.front(), buff.size(), md ); rx_stream->recv( //again for the inline message &buff.front(), buff.size(), md ); switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN: std::cout << boost::format( "success:\n" " Got error code broken chain message.\n" ) << std::endl; return true; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: std::cout << boost::format( "failed:\n" " Inline message recv timed out.\n" ) << std::endl; return false; default: std::cout << boost::format( "failed:\n" " Got unexpected error code 0x%x.\n" ) % md.error_code << std::endl; return false; } }
/*! * Test the late command message: * Issue a stream command with a time that is in the past. * We expect to get an inline late command message. */ bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ std::cout << "Test late command message... " << std::flush; usrp->set_time_now(uhd::time_spec_t(200.0)); //set time uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = rx_stream->get_max_num_samps(); stream_cmd.stream_now = false; stream_cmd.time_spec = uhd::time_spec_t(100.0); //time in the past rx_stream->issue_stream_cmd(stream_cmd); std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); uhd::rx_metadata_t md; const size_t nsamps = rx_stream->recv( &buff.front(), buff.size(), md ); switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: std::cout << boost::format( "success:\n" " Got error code late command message.\n" ) << std::endl; return true; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: std::cout << boost::format( "failed:\n" " Inline message recv timed out.\n" ) << std::endl; return false; default: std::cout << boost::format( "failed:\n" " Got unexpected error code 0x%x, nsamps %u.\n" ) % md.error_code % nsamps << std::endl; return false; } }
// Thread to import data from the USRP !Size of the arrays in complex -> 2*buffer_size ! void usrpGetData(uhd::rx_streamer::sptr rx_stream, uhd::usrp::multi_usrp::sptr dev, size_t buffer_size, board_60GHz_RX *my_60GHz_RX) { // Set priority of the thread int which = PRIO_PROCESS; id_t pid; int priority = -20; int ret; pid = getpid(); ret = setpriority(which, pid, priority); if(ret!=0) { std::cout << "Main priority went wrong in usrpT: " << ret << std::endl ; } // Create storage for a single buffer from USRP short *buff_short; buff_short=new short[2*buffer_size]; size_t n_rx_last; uhd::rx_metadata_t md; //int time=buffer_size/(25)-100; // microsecondes while (1) { n_rx_last=0; // Fill buff_short while (n_rx_last==0) { n_rx_last=rx_stream->recv(&buff_short[0], buffer_size, md, 3.0); std::this_thread::yield(); // Avoid active waiting }; // Check if no overflow if (n_rx_last!=buffer_size) { std::cerr << "I expect the buffer size to be always the same!\n"; std::cout<<"Read only:"<<n_rx_last<<"\n"; std::cout<<"Buffer:"<<buffer_size<<"\n"; //exit(1); }; // Add the just received buffer to the queue mtxUsrp.lock(); usrpQ.push(buff_short); mtxUsrp.unlock(); // Change memory cell used buff_short=new short [2*buffer_size]; // Gives the start to detection part sem_post( &usrpReady); }//end while 1 }
void rx_worker( uhd::rx_streamer::sptr rx_stream, unsigned int samps_per_pulse, std::vector<std::complex<int16_t>* >& recv_ptr ){ uhd::rx_metadata_t rxmd; float timeout = 1.1; rxmd.error_code = uhd::rx_metadata_t::ERROR_CODE_NONE; size_t nrx_samples = rx_stream->recv(recv_ptr, samps_per_pulse, rxmd, timeout); if (rxmd.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ std::cerr << "Error!\t"; std::cerr << rxmd.error_code << std::endl; } }
// Thread to import data from the USRP !Size of the arrays in complex -> 2*buffer_size ! void usrpGetData(uhd::rx_streamer::sptr rx_stream,uhd::usrp::multi_usrp::sptr dev, size_t buffer_size){ // Set highest priority for this thread set_realtime_priority(); // Create storage for a single buffer from USRP short *buff_short; buff_short=new short[2*buffer_size]; // Initialisation size_t n_rx_last; uhd::rx_metadata_t md; //int time=buffer_size/(25)-100; // microsecondes while (1){ n_rx_last=0; // Fill buff_short while (n_rx_last==0) { n_rx_last=rx_stream->recv(&buff_short[0], buffer_size, md, 3.0); std::this_thread::yield(); // Avoid active waiting }; // Check if no overflow if (n_rx_last!=buffer_size) { std::cerr << "I expect the buffer size to be always the same!\n"; std::cout<<"Read only:"<<n_rx_last<<"\n"; std::cout<<"Buffer:"<<buffer_size<<"\n"; //exit(1); }; // Add the just received buffer to the queue mtxUsrp.lock(); usrpQ.push(buff_short); mtxUsrp.unlock(); // Change memory cell used buff_short=new short [2*buffer_size]; // Gives the start to detection part sem_post( &usrpReady); std::this_thread::sleep_for(std::chrono::microseconds(5)); }//end while 1 }
int uhd_device::readSamples(short *buf, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun, unsigned *RSSI) { ssize_t rc; uhd::time_spec_t ts; uhd::rx_metadata_t metadata; uint32_t pkt_buf[rx_spp]; if (skip_rx) return 0; *overrun = false; *underrun = false; // Shift read time with respect to transmit clock timestamp += ts_offset; ts = convert_time(timestamp, rx_rate); LOG(DEBUG) << "Requested timestamp = " << ts.get_real_secs(); // Check that timestamp is valid rc = rx_smpl_buf->avail_smpls(timestamp); if (rc < 0) { LOG(ERR) << rx_smpl_buf->str_code(rc); LOG(ERR) << rx_smpl_buf->str_status(); return 0; } // Receive samples from the usrp until we have enough while (rx_smpl_buf->avail_smpls(timestamp) < len) { size_t num_smpls = rx_stream->recv( (void*)pkt_buf, rx_spp, metadata, 0.1, true); rx_pkt_cnt++; // Check for errors rc = check_rx_md_err(metadata, num_smpls); switch (rc) { case ERROR_UNRECOVERABLE: LOG(ALERT) << "UHD: Version " << uhd::get_version_string(); LOG(ALERT) << "UHD: Unrecoverable error, exiting..."; exit(-1); case ERROR_TIMING: restart(prev_ts); case ERROR_UNHANDLED: continue; } ts = metadata.time_spec; LOG(DEBUG) << "Received timestamp = " << ts.get_real_secs(); rc = rx_smpl_buf->write(pkt_buf, num_smpls, metadata.time_spec); // Continue on local overrun, exit on other errors if ((rc < 0)) { LOG(ERR) << rx_smpl_buf->str_code(rc); LOG(ERR) << rx_smpl_buf->str_status(); if (rc != smpl_buf::ERROR_OVERFLOW) return 0; } } // We have enough samples rc = rx_smpl_buf->read(buf, len, timestamp); if ((rc < 0) || (rc != len)) { LOG(ERR) << rx_smpl_buf->str_code(rc); LOG(ERR) << rx_smpl_buf->str_status(); return 0; } return len; }
int uhd_device::open(const std::string &args, bool extref) { // Find UHD devices uhd::device_addr_t addr(args); uhd::device_addrs_t dev_addrs = uhd::device::find(addr); if (dev_addrs.size() == 0) { LOG(ALERT) << "No UHD devices found with address '" << args << "'"; return -1; } // Use the first found device LOG(INFO) << "Using discovered UHD device " << dev_addrs[0].to_string(); try { usrp_dev = uhd::usrp::multi_usrp::make(dev_addrs[0]); } catch(...) { LOG(ALERT) << "UHD make failed, device " << dev_addrs[0].to_string(); return -1; } // Check for a valid device type and set bus type if (!parse_dev_type()) return -1; if (extref) set_ref_clk(true); // Create TX and RX streamers uhd::stream_args_t stream_args("sc16"); tx_stream = usrp_dev->get_tx_stream(stream_args); rx_stream = usrp_dev->get_rx_stream(stream_args); // Number of samples per over-the-wire packet tx_spp = tx_stream->get_max_num_samps(); rx_spp = rx_stream->get_max_num_samps(); // Set rates double _tx_rate = select_rate(dev_type, sps); double _rx_rate = _tx_rate / sps; if ((_tx_rate > 0.0) && (set_rates(_tx_rate, _rx_rate) < 0)) return -1; // Create receive buffer size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t); rx_smpl_buf = new smpl_buf(buf_len, rx_rate); // Set receive chain sample offset double offset = get_dev_offset(dev_type, sps); if (offset == 0.0) { LOG(ERR) << "Unsupported configuration, no correction applied"; ts_offset = 0; } else { ts_offset = (TIMESTAMP) (offset * rx_rate); } // Initialize and shadow gain values init_gains(); // Print configuration LOG(INFO) << "\n" << usrp_dev->get_pp_string(); switch (dev_type) { case B100: return RESAMP_64M; case USRP2: case X3XX: return RESAMP_100M; } return NORMAL; }
void recv_to_file(uhd::rx_streamer::sptr rx_stream, const std::string& file, const size_t samps_per_buff, const double rx_rate, const unsigned long long num_requested_samples, double time_requested = 0.0, bool bw_summary = false, bool stats = false, bool enable_size_map = false, bool continue_on_bad_packet = false) { unsigned long long num_total_samps = 0; uhd::rx_metadata_t md; std::vector<samp_type> buff(samps_per_buff); std::ofstream outfile; if (not file.empty()) { outfile.open(file.c_str(), std::ofstream::binary); } bool overflow_message = true; // setup streaming uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = size_t(num_requested_samples); stream_cmd.stream_now = true; stream_cmd.time_spec = uhd::time_spec_t(); std::cout << "Issuing stream cmd" << std::endl; rx_stream->issue_stream_cmd(stream_cmd); const auto start_time = std::chrono::steady_clock::now(); const auto stop_time = start_time + std::chrono::milliseconds(int64_t(1000 * time_requested)); // Track time and samps between updating the BW summary auto last_update = start_time; unsigned long long last_update_samps = 0; typedef std::map<size_t, size_t> SizeMap; SizeMap mapSizes; // Run this loop until either time expired (if a duration was given), until // the requested number of samples were collected (if such a number was // given), or until Ctrl-C was pressed. while (not stop_signal_called and (num_requested_samples != num_total_samps or num_requested_samples == 0) and (time_requested == 0.0 or std::chrono::steady_clock::now() <= stop_time)) { const auto now = std::chrono::steady_clock::now(); size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md, 3.0, enable_size_map); if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { std::cout << boost::format("Timeout while streaming") << std::endl; break; } if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) { if (overflow_message) { overflow_message = false; std::cerr << boost::format( "Got an overflow indication. Please consider the following:\n" " Your write medium must sustain a rate of %fMB/s.\n" " Dropped samples will not be written to the file.\n" " Please modify this example for your purposes.\n" " This message will not appear again.\n") % (rx_rate * sizeof(samp_type) / 1e6); } continue; } if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::string error = str(boost::format("Receiver error: %s") % md.strerror()); if (continue_on_bad_packet) { std::cerr << error << std::endl; continue; } else throw std::runtime_error(error); } if (enable_size_map) { SizeMap::iterator it = mapSizes.find(num_rx_samps); if (it == mapSizes.end()) mapSizes[num_rx_samps] = 0; mapSizes[num_rx_samps] += 1; } num_total_samps += num_rx_samps; if (outfile.is_open()) { outfile.write((const char*)&buff.front(), num_rx_samps * sizeof(samp_type)); } if (bw_summary) { last_update_samps += num_rx_samps; const auto time_since_last_update = now - last_update; if (time_since_last_update > std::chrono::seconds(UPDATE_INTERVAL)) { const double time_since_last_update_s = std::chrono::duration<double>(time_since_last_update).count(); const double rate = double(last_update_samps) / time_since_last_update_s; std::cout << "\t" << (rate / 1e6) << " MSps" << std::endl; last_update_samps = 0; last_update = now; } } } const auto actual_stop_time = std::chrono::steady_clock::now(); stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; std::cout << "Issuing stop stream cmd" << std::endl; rx_stream->issue_stream_cmd(stream_cmd); // Run recv until nothing is left int num_post_samps = 0; do { num_post_samps = rx_stream->recv(&buff.front(), buff.size(), md, 3.0); } while (num_post_samps and md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE); if (outfile.is_open()) outfile.close(); if (stats) { std::cout << std::endl; const double actual_duration_seconds = std::chrono::duration<float>(actual_stop_time - start_time).count(); std::cout << boost::format("Received %d samples in %f seconds") % num_total_samps % actual_duration_seconds << std::endl; const double rate = (double)num_total_samps / actual_duration_seconds; std::cout << (rate / 1e6) << " MSps" << std::endl; if (enable_size_map) { std::cout << std::endl; std::cout << "Packet size map (bytes: count)" << std::endl; for (SizeMap::iterator it = mapSizes.begin(); it != mapSizes.end(); it++) std::cout << it->first << ":\t" << it->second << std::endl; } } }
/*********************************************************************** * Benchmark RX Rate **********************************************************************/ void benchmark_rx_rate( uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_cpu, uhd::rx_streamer::sptr rx_stream, bool random_nsamps, const boost::posix_time::ptime &start_time, std::atomic<bool>& burst_timer_elapsed ) { uhd::set_thread_priority_safe(); //print pre-test summary std::cout << boost::format( "[%s] Testing receive rate %f Msps on %u channels" ) % NOW() % (usrp->get_rx_rate()/1e6) % rx_stream->get_num_channels() << std::endl; //setup variables and allocate buffer uhd::rx_metadata_t md; const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(rx_cpu)); std::vector<void *> buffs; for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) buffs.push_back(&buff.front()); //same buffer for each channel bool had_an_overflow = false; uhd::time_spec_t last_time; const double rate = usrp->get_rx_rate(); uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY); cmd.stream_now = (buffs.size() == 1); rx_stream->issue_stream_cmd(cmd); const float burst_pkt_time = std::max<float>(0.100f, (2 * max_samps_per_packet/rate)); float recv_timeout = burst_pkt_time + INIT_DELAY; bool stop_called = false; while (true) { //if (burst_timer_elapsed.load(boost::memory_order_relaxed) and not stop_called) { if (burst_timer_elapsed and not stop_called) { rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); stop_called = true; } if (random_nsamps) { cmd.num_samps = rand() % max_samps_per_packet; rx_stream->issue_stream_cmd(cmd); } try { num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, recv_timeout)*rx_stream->get_num_channels(); recv_timeout = burst_pkt_time; } catch (uhd::io_error &e) { std::cerr << "[" << NOW() << "] Caught an IO exception. " << std::endl; std::cerr << e.what() << std::endl; return; } //handle the error codes switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_NONE: if (had_an_overflow) { had_an_overflow = false; const long dropped_samps = (md.time_spec - last_time).to_ticks(rate); if (dropped_samps < 0) { std::cerr << "[" << NOW() << "] Timestamp after overrun recovery " "ahead of error timestamp! Unable to calculate " "number of dropped samples." "(Delta: " << dropped_samps << " ticks)\n"; } num_dropped_samps += std::max<long>(1, dropped_samps); } if ((burst_timer_elapsed or stop_called) and md.end_of_burst) { return; } break; // ERROR_CODE_OVERFLOW can indicate overflow or sequence error case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: last_time = md.time_spec; had_an_overflow = true; // check out_of_sequence flag to see if it was a sequence error or overflow if (!md.out_of_sequence) { num_overruns++; } else { num_seqrx_errors++; std::cerr << "[" << NOW() << "] Detected Rx sequence error." << std::endl; } break; case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << ", restart streaming..."<< std::endl; num_late_commands++; // Radio core will be in the idle state. Issue stream command to restart streaming. cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); cmd.stream_now = (buffs.size() == 1); rx_stream->issue_stream_cmd(cmd); break; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: if (burst_timer_elapsed) { return; } std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << ", continuing..." << std::endl; num_timeouts_rx++; break; // Otherwise, it's an error default: std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << std::endl; std::cerr << "[" << NOW() << "] Unexpected error on recv, continuing..." << std::endl; break; } } }
void storeDataX(uhd::rx_streamer::sptr rx_stream, uhd::usrp::multi_usrp::sptr dev, size_t buffer_size, uint nDetect){ // Create storage for a single buffer from USRP short *buff_short; buff_short=new short[2*buffer_size]; short *storage_short; storage_short=new short [2*nDetect]; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); std::cout << "Stop the transmitter by pressing ctrl-c \n"; stream_cmd.num_samps = buffer_size; stream_cmd.stream_now = true; stream_cmd.stream_mode=uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; dev->issue_stream_cmd(stream_cmd); uhd::rx_metadata_t md; size_t n_rx_samps=0; int n_rx_last; while (1){ n_rx_samps=0; // Fill the storage buffer loop while (n_rx_samps<nDetect){ n_rx_last=0; // Fill buff_short while (n_rx_last==0) { n_rx_last=rx_stream->recv(&buff_short[0], buffer_size, md, 3.0); //std::this_thread::yield(); }; sec_count++; // Check if no overflow if (n_rx_last!=(int)buffer_size) { std::cerr << "I expect the buffer size to be always the same!\n"; std::cout<<"Read only:"<<n_rx_last<<"\n"; std::cout<<"Buffer:"<<buffer_size<<"\n"; exit(1); }; // Fill storage int i1=2*n_rx_samps; int i2=0; while ((i1<(int) (2*nDetect)) && (i2<2*((int) buffer_size))){ storage_short[i1]=buff_short[i2]; i1++; i2++; }; //storage_short=buff_short; n_rx_samps=n_rx_samps+n_rx_last; //std::cout << "n_rx_samps=" << n_rx_samps << std::endl; }//storage_short now full mtxQ.lock(); bufferQ.push(buff_short); mtxQ.unlock(); //delete buff_short; buff_short=new short [2*buffer_size]; // Change memory cell used //usleep(1000000/4); sem_post( &isReady); // Gives the start to detection part }//end while 1 }