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;
}
Example #2
0
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;
}