int uhd_device::readSamples(float *buf, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun, unsigned *RSSI) { ssize_t rc; uhd::time_spec_t ts; uhd::rx_metadata_t metadata; uint64_t pkt_buf[rx_spp]; if (skip_rx) return 0; // Shift read time with respect to transmit clock timestamp += ts_offset; ts = convert_time(timestamp, actual_smpl_rt); 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 = usrp_dev->get_device()->recv( (void*)pkt_buf, rx_spp, metadata, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::RECV_MODE_ONE_PACKET); 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 UHDDevice::readSamples(short *buf, int len, bool *overrun, long long timestamp, bool *underrun, unsigned *RSSI) { ssize_t rc; uhd::time_spec_t timespec; uhd::rx_metadata_t metadata; uint32_t pkt_buf[rx_spp]; *overrun = false; *underrun = false; /* Align read time sample timing with respect to transmit clock */ timestamp += ts_offset; timespec = uhd::time_spec_t::from_ticks(timestamp, rx_rate); LOG(DEBUG) << "Requested timestamp = " << timestamp; /* Check that timestamp is valid */ rc = rx_buffer->avail_smpls(timestamp); if (rc < 0) { LOG(ERR) << rx_buffer->str_code(rc); LOG(ERR) << rx_buffer->str_status(timestamp); return 0; } /* Receive samples from the usrp until we have enough */ while (rx_buffer->avail_smpls(timestamp) < len) { thread_enable_cancel(false); size_t num_smpls = rx_stream->recv( (void *) pkt_buf, rx_spp, metadata, 0.1, true); thread_enable_cancel(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: case ERROR_UNHANDLED: continue; } timespec = metadata.time_spec; LOG(DEBUG) << "Received timestamp = " << timespec.to_ticks(rx_rate); rc = rx_buffer->write(pkt_buf, num_smpls, metadata.time_spec); /* Continue on local overrun, exit on other errors */ if ((rc < 0)) { LOG(ERR) << rx_buffer->str_code(rc); LOG(ERR) << rx_buffer->str_status(timestamp); if (rc != SampleBuffer::ERROR_OVERFLOW) return 0; } } /* We have enough samples */ rc = rx_buffer->read(buf, len, timestamp); if ((rc < 0) || (rc != len)) { LOG(ERR) << rx_buffer->str_code(rc); LOG(ERR) << rx_buffer->str_status(timestamp); return 0; } return len; }