/*
* Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "radioDevice.h"
#include "Threads.h"
#include "Logger.h"
#include <uhd/usrp/single_usrp.hpp>
#include <uhd/utils/thread_priority.hpp>

/*
    use_ext_ref       - Enable external 10MHz clock reference

    master_clk_rt     - Master clock frequency

    rx_smpl_offset    - Timing correction in seconds between receive and
                        transmit timestamps. This value corrects for delays on
                        on the RF side of the timestamping point of the device.
                        This value is generally empirically measured.

    smpl_buf_sz       - The receive sample buffer size in bytes.

    tx_ampl           - Transmit amplitude must be between 0 and 1.0
*/
const bool use_ext_ref = false;
const double master_clk_rt = 52e6;
const double rx_smpl_offset = .0000869;
const size_t smpl_buf_sz = (1 << 20);
const float tx_ampl = .3;

/** Timestamp conversion
    @param timestamp a UHD or OpenBTS timestamp
    @param rate sample rate
    @return the converted timestamp
*/
uhd::time_spec_t convert_time(TIMESTAMP ticks, double rate)
{
	double secs = (double) ticks / rate;
	return uhd::time_spec_t(secs);
}

TIMESTAMP convert_time(uhd::time_spec_t ts, double rate)
{
	TIMESTAMP ticks = ts.get_full_secs() * rate;
	return ts.get_tick_count(rate) + ticks;
}

/*
    Sample Buffer - Allows reading and writing of timed samples using OpenBTS
                    or UHD style timestamps. Time conversions are handled
                    internally or accessable through the static convert calls.
*/
class smpl_buf {
public:
	/** Sample buffer constructor
	    @param len number of 32-bit samples the buffer should hold
	    @param rate sample clockrate 
	    @param timestamp 
	*/
	smpl_buf(size_t len, double rate);
	~smpl_buf();

	/** Query number of samples available for reading
	    @param timestamp time of first sample
	    @return number of available samples or error
	*/
	ssize_t avail_smpls(TIMESTAMP timestamp) const;
	ssize_t avail_smpls(uhd::time_spec_t timestamp) const;

	/** Read and write
	    @param buf pointer to buffer
	    @param len number of samples desired to read or write
	    @param timestamp time of first stample
	    @return number of actual samples read or written or error
	*/
	ssize_t read(void *buf, size_t len, TIMESTAMP timestamp);
	ssize_t read(void *buf, size_t len, uhd::time_spec_t timestamp);
	ssize_t write(void *buf, size_t len, TIMESTAMP timestamp);
	ssize_t write(void *buf, size_t len, uhd::time_spec_t timestamp);

	/** Buffer status string
	    @return a formatted string describing internal buffer state
	*/
	std::string str_status() const;

	/** Formatted error string 
	    @param code an error code
	    @return a formatted error string
	*/
	static std::string str_code(ssize_t code);

	enum err_code {
		ERROR_TIMESTAMP = -1,
		ERROR_READ = -2,
		ERROR_WRITE = -3,
		ERROR_OVERFLOW = -4
	};

private:
	uint32_t *data;
	size_t buf_len;

	double clk_rt;

	TIMESTAMP time_start;
	TIMESTAMP time_end;

	size_t data_start;
	size_t data_end;
};

/*
    uhd_device - UHD implementation of the Device interface. Timestamped samples
                are sent to and received from the device. An intermediate buffer
                on the receive side collects and aligns packets of samples.
                Events and errors such as underruns are reported asynchronously
                by the device and received in a separate thread.
*/
class uhd_device : public RadioDevice {
public:
	uhd_device(double rate, bool skip_rx);
	~uhd_device();

	bool open();
	bool start();
	bool stop();
	void restart(uhd::time_spec_t ts);
	void setPriority();

	int readSamples(short *buf, int len, bool *overrun, 
			TIMESTAMP timestamp, bool *underrun, unsigned *RSSI);

	int writeSamples(short *buf, int len, bool *underrun, 
			 TIMESTAMP timestamp, bool isControl);

	bool updateAlignment(TIMESTAMP timestamp);

	bool setTxFreq(double wFreq);
	bool setRxFreq(double wFreq);

	inline TIMESTAMP initialWriteTimestamp() { return 0; }
	inline TIMESTAMP initialReadTimestamp() { return 0; }

	inline double fullScaleInputValue() { return 32000 * tx_ampl; }
	inline double fullScaleOutputValue() { return 32000; }

	double setRxGain(double db);
	double getRxGain(void) { return rx_gain; }
	double maxRxGain(void) { return rx_gain_max; }
	double minRxGain(void) { return rx_gain_min; }

	double setTxGain(double db);
	double maxTxGain(void) { return tx_gain_max; }
	double minTxGain(void) { return tx_gain_min; }

	double getTxFreq() { return tx_freq; }
	double getRxFreq() { return rx_freq; }

	inline double getSampleRate() { return actual_smpl_rt; }
	inline double numberRead() { return rx_pkt_cnt; }
	inline double numberWritten() { return 0; }

	/** Receive and process asynchronous message
	    @return true if message received or false on timeout or error
	*/
	bool recv_async_msg();

	enum err_code {
		ERROR_TIMING = -1,
		ERROR_UNRECOVERABLE = -2,
		ERROR_UNHANDLED = -3,
	};

private:
	uhd::usrp::single_usrp::sptr usrp_dev;

	double desired_smpl_rt, actual_smpl_rt;

	double tx_gain, tx_gain_min, tx_gain_max;
	double rx_gain, rx_gain_min, rx_gain_max;

	double tx_freq, rx_freq;
	size_t tx_spp, rx_spp;

	bool started;
	bool aligned;
	bool skip_rx;

	size_t rx_pkt_cnt;
	size_t drop_cnt;
	uhd::time_spec_t prev_ts;

	TIMESTAMP ts_offset;
	smpl_buf *rx_smpl_buf;

	void init_gains();
	void set_ref_clk(bool ext_clk);
	double set_rates(double rate);
	bool flush_recv(size_t num_pkts);
	int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);

	std::string str_code(uhd::rx_metadata_t metadata);
	std::string str_code(uhd::async_metadata_t metadata);

	Thread async_event_thrd;
};

void *async_event_loop(uhd_device *dev)
{
	while (1) {
		dev->recv_async_msg();
		pthread_testcancel();
	}
}

uhd_device::uhd_device(double rate, bool skip_rx)
	: desired_smpl_rt(rate), actual_smpl_rt(0),
	  tx_gain(0.0), tx_gain_min(0.0), tx_gain_max(0.0),
	  rx_gain(0.0), rx_gain_min(0.0), rx_gain_max(0.0),
	  tx_freq(0.0), rx_freq(0.0), tx_spp(0), rx_spp(0),
	  started(false), aligned(false), rx_pkt_cnt(0), drop_cnt(0),
	  prev_ts(0,0), ts_offset(0), rx_smpl_buf(NULL)
{
	this->skip_rx = skip_rx;
}

uhd_device::~uhd_device()
{
	stop();

	if (rx_smpl_buf)
		delete rx_smpl_buf;
}

void uhd_device::init_gains()
{
	uhd::gain_range_t range;

	range = usrp_dev->get_tx_gain_range();
	tx_gain_min = range.start();
	tx_gain_max = range.stop();

	range = usrp_dev->get_rx_gain_range();
	rx_gain_min = range.start();
	rx_gain_max = range.stop();

	usrp_dev->set_tx_gain((tx_gain_min + tx_gain_max) / 2);
	usrp_dev->set_rx_gain((rx_gain_min + rx_gain_max) / 2);

	tx_gain = usrp_dev->get_tx_gain();
	rx_gain = usrp_dev->get_rx_gain();

	return;
}

void uhd_device::set_ref_clk(bool ext_clk)
{
	uhd::clock_config_t clk_cfg;

	clk_cfg.pps_source = uhd::clock_config_t::PPS_SMA;

	if (ext_clk)
		clk_cfg.ref_source = uhd::clock_config_t::REF_SMA;
	else
		clk_cfg.ref_source = uhd::clock_config_t::REF_INT;

	usrp_dev->set_clock_config(clk_cfg);

	return;
}

double uhd_device::set_rates(double rate)
{
	double actual_rt, actual_clk_rt;

	// Set master clock rate
	usrp_dev->set_master_clock_rate(master_clk_rt);
	actual_clk_rt = usrp_dev->get_master_clock_rate();

	if (actual_clk_rt != master_clk_rt) {
		LOG(ERROR) << "Failed to set master clock rate";
		return -1.0;
	}

	// Set sample rates
	usrp_dev->set_tx_rate(rate);
	usrp_dev->set_rx_rate(rate);
	actual_rt = usrp_dev->get_tx_rate();

	if (actual_rt != rate) {
		LOG(ERROR) << "Actual sample rate differs from desired rate";
		return -1.0;
	}
	if (usrp_dev->get_rx_rate() != actual_rt) {
		LOG(ERROR) << "Transmit and receive sample rates do not match";
		return -1.0;
	}

	return actual_rt;
}

double uhd_device::setTxGain(double db)
{
	usrp_dev->set_tx_gain(db);
	tx_gain = usrp_dev->get_tx_gain();

	LOG(INFO) << "Set TX gain to " << tx_gain << "dB";

	return tx_gain;
}

double uhd_device::setRxGain(double db)
{
	usrp_dev->set_rx_gain(db);
	rx_gain = usrp_dev->get_rx_gain();

	LOG(INFO) << "Set RX gain to " << rx_gain << "dB";

	return rx_gain;
}

bool uhd_device::open()
{
	LOG(INFO) << "creating USRP device...";

	// Allow all UHD devices
	uhd::device_addr_t dev_addr("");
	try {
		usrp_dev = uhd::usrp::single_usrp::make(dev_addr);
	}
	
	catch(...) {
		LOG(ERROR) << "USRP make failed";
		return false;
	}

	// Number of samples per over-the-wire packet
	tx_spp = usrp_dev->get_device()->get_max_send_samps_per_packet();
	rx_spp = usrp_dev->get_device()->get_max_recv_samps_per_packet();

	// Set rates
	actual_smpl_rt = set_rates(desired_smpl_rt);
	if (actual_smpl_rt < 0)
		return false;

	// Create receive buffer
	size_t buf_len = smpl_buf_sz / sizeof(uint32_t);
	rx_smpl_buf = new smpl_buf(buf_len, actual_smpl_rt);

	// Set receive chain sample offset 
	ts_offset = (TIMESTAMP)(rx_smpl_offset * actual_smpl_rt);

	// Initialize and shadow gain values 
	init_gains();

	// Set reference clock
	set_ref_clk(use_ext_ref);

	// Print configuration
	LOG(INFO) << usrp_dev->get_pp_string();

	return true;
}

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 = usrp_dev->get_device()->recv(
					buff,
					rx_spp,
					md,
					uhd::io_type_t::COMPLEX_INT16,
					uhd::device::RECV_MODE_ONE_PACKET,
					timeout);

		if (!num_smpls) {
			switch (md.error_code) {
			case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
				return true;
			default:
				continue;
			}
		}
	}

	return true;
}

void uhd_device::restart(uhd::time_spec_t ts)
{
	uhd::stream_cmd_t cmd = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
	usrp_dev->issue_stream_cmd(cmd);

	flush_recv(50);

	usrp_dev->set_time_now(ts);
	aligned = false;

	cmd = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
	cmd.stream_now = true;
	usrp_dev->issue_stream_cmd(cmd);
}

bool uhd_device::start()
{
	LOG(INFO) << "Starting USRP...";

	if (started) {
		LOG(ERROR) << "Device already started";
		return false;
	}

	setPriority();

	// Start asynchronous event (underrun check) loop
	async_event_thrd.start((void * (*)(void*))async_event_loop, (void*)this);

	// Start streaming
	restart(uhd::time_spec_t(0.0));

	// Display usrp time
	double time_now = usrp_dev->get_time_now().get_real_secs();
	LOG(INFO) << "The current time is " << time_now << " seconds";

	started = true;
	return true;
}

bool uhd_device::stop()
{
	uhd::stream_cmd_t stream_cmd = 
		uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;

	usrp_dev->issue_stream_cmd(stream_cmd);

	started = false;
	return true;
}

void uhd_device::setPriority()
{
	uhd::set_thread_priority_safe();
	return;
}

int uhd_device::check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls)
{
	uhd::time_spec_t ts;

	if (!num_smpls) {
		LOG(ERROR) << str_code(md);

		switch (md.error_code) {
		case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
			return ERROR_UNRECOVERABLE;
		case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
		case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND:
		case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN:
		case uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET:
		default:
			return ERROR_UNHANDLED;
		}
	}

	// Missing timestamp
	if (!md.has_time_spec) {
		LOG(ERROR) << "UHD: Received packet missing timestamp";
		return ERROR_UNRECOVERABLE;
	}

	ts = md.time_spec;

	// Monotonicity check
	if (ts < prev_ts) {
		LOG(ERROR) << "UHD: Loss of monotonic: " << ts.get_real_secs();
		LOG(ERROR) << "UHD: Previous time: " << prev_ts.get_real_secs();
		return ERROR_TIMING;
	} else {
		prev_ts = ts;
	}

	return 0;
}

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;

	// Shift read time with respect to transmit clock
	timestamp += ts_offset;

	ts = convert_time(timestamp, actual_smpl_rt);
	LOG(DEEPDEBUG) << "Requested timestamp = " << ts.get_real_secs();

	// Check that timestamp is valid
	rc = rx_smpl_buf->avail_smpls(timestamp);
	if (rc < 0) {
		LOG(ERROR) << rx_smpl_buf->str_code(rc);
		LOG(ERROR) << 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_INT16,
					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(ERROR) << "UHD: Unrecoverable error, exiting.";
			exit(-1);
		case ERROR_TIMING:
			restart(prev_ts);
		case ERROR_UNHANDLED:
			return 0;
		}


		ts = metadata.time_spec;
		LOG(DEEPDEBUG) << "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(ERROR) << rx_smpl_buf->str_code(rc);
			LOG(ERROR) << 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(ERROR) << rx_smpl_buf->str_code(rc);
		LOG(ERROR) << rx_smpl_buf->str_status();
		return 0;
	}

	return len;
}

int uhd_device::writeSamples(short *buf, int len, bool *underrun,
			unsigned long long timestamp,bool isControl)
{
	uhd::tx_metadata_t metadata;
	metadata.has_time_spec = true;
	metadata.start_of_burst = false;
	metadata.end_of_burst = false;
	metadata.time_spec = convert_time(timestamp, actual_smpl_rt);

	// No control packets
	if (isControl) {
		LOG(ERROR) << "Control packets not supported";
		return 0;
	}

	// Drop a fixed number of packets (magic value)
	if (!aligned) {
		drop_cnt++;

		if (drop_cnt == 1) {
			LOG(DEBUG) << "Aligning transmitter: stop burst";
			metadata.end_of_burst = true;
		} else if (drop_cnt < 30) {
			LOG(DEEPDEBUG) << "Aligning transmitter: packet advance";
			*underrun = true;
			return len;
		} else {
			LOG(DEBUG) << "Aligning transmitter: start burst";
			metadata.start_of_burst = true;
			aligned = true;
			drop_cnt = 0;
		}
	}

	size_t num_smpls = usrp_dev->get_device()->send(buf,
					len,
					metadata,
					uhd::io_type_t::COMPLEX_INT16,
					uhd::device::SEND_MODE_FULL_BUFF);

	if (num_smpls != (unsigned)len)
		LOG(ERROR) << "UHD: Sent fewer samples than requested";

	return num_smpls;
}

bool uhd_device::updateAlignment(TIMESTAMP timestamp)
{
	aligned = false;
	return true;
}

bool uhd_device::setTxFreq(double wFreq)
{
	uhd::tune_result_t tr = usrp_dev->set_tx_freq(wFreq);
	LOG(INFO) << tr.to_pp_string();
	tx_freq = usrp_dev->get_tx_freq();

	return true;
}

bool uhd_device::setRxFreq(double wFreq)
{
	uhd::tune_result_t tr = usrp_dev->set_rx_freq(wFreq);
	LOG(INFO) << tr.to_pp_string();
	rx_freq = usrp_dev->get_rx_freq();

	return true;
}

bool uhd_device::recv_async_msg()
{
	uhd::async_metadata_t metadata;
	if (!usrp_dev->get_device()->recv_async_msg(metadata))
		return false;

	// Assume that any error requires resynchronization
	if (metadata.event_code != uhd::async_metadata_t::EVENT_CODE_BURST_ACK) {
		aligned = false;
		LOG(ERROR) << str_code(metadata);
	}

	return true;
}

std::string uhd_device::str_code(uhd::rx_metadata_t metadata)
{
	std::ostringstream ost("UHD: ");

	switch (metadata.error_code) {
	case uhd::rx_metadata_t::ERROR_CODE_NONE:
		ost << "No error";
		break;
	case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
		ost << "No packet received, implementation timed-out";
		break;
	case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND:
		ost << "A stream command was issued in the past";
		break;
	case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN:
		ost << "Expected another stream command";
		break;
	case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
		ost << "An internal receive buffer has filled";
		break;
	case uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET:
		ost << "The packet could not be parsed";
		break;
	default:
		ost << "Unknown error " << metadata.error_code;
	}

	if (metadata.has_time_spec)
		ost << " at " << metadata.time_spec.get_real_secs() << " sec.";

	return ost.str();
}

std::string uhd_device::str_code(uhd::async_metadata_t metadata)
{
	std::ostringstream ost("UHD: ");

	switch (metadata.event_code) {
	case uhd::async_metadata_t::EVENT_CODE_BURST_ACK:
		ost << "A packet was successfully transmitted";
		break;
	case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW:
		ost << "An internal send buffer has emptied";
		break;
	case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR:
		ost << "Packet loss between host and device";
		break;
	case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR:
		ost << "Packet time was too late or too early";
		break;
	case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET:
		ost << "Underflow occurred inside a packet";
		break;
	case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST:
		ost << "Packet loss within a burst";
		break;
	default:
		ost << "Unknown error " << metadata.event_code;
	}

	if (metadata.has_time_spec)
		ost << " at " << metadata.time_spec.get_real_secs() << " sec.";

	return ost.str();
}

smpl_buf::smpl_buf(size_t len, double rate)
	: buf_len(len), clk_rt(rate),
	  time_start(0), time_end(0), data_start(0), data_end(0)
{
	data = new uint32_t[len];
}

smpl_buf::~smpl_buf()
{
	delete[] data;
}

ssize_t smpl_buf::avail_smpls(TIMESTAMP timestamp) const
{
	if (timestamp < time_start)
		return ERROR_TIMESTAMP;
	else if (timestamp >= time_end)
		return 0;
	else
		return time_end - timestamp;
}

ssize_t smpl_buf::avail_smpls(uhd::time_spec_t timespec) const
{
	return avail_smpls(convert_time(timespec, clk_rt));
}

ssize_t smpl_buf::read(void *buf, size_t len, TIMESTAMP timestamp)
{
	// Check for valid read
	if (timestamp < time_start)
		return ERROR_TIMESTAMP;
	if (timestamp >= time_end)
		return 0;
	if (len >= buf_len)
		return ERROR_READ;

	// How many samples should be copied
	size_t num_smpls = time_end - timestamp;
	if (num_smpls > len);
		num_smpls = len;

	// Starting index
	size_t read_start = data_start + (timestamp - time_start);

	// Read it
	if (read_start + num_smpls < buf_len) {
		size_t numBytes = len * 2 * sizeof(short);
		memcpy(buf, data + read_start, numBytes);
	} else {
		size_t first_cp = (buf_len - read_start) * 2 * sizeof(short);
		size_t second_cp = len * 2 * sizeof(short) - first_cp;

		memcpy(buf, data + read_start, first_cp);
		memcpy((char*) buf + first_cp, data, second_cp);
	}

	data_start = (read_start + len) % buf_len;
	time_start = timestamp + len;

	if (time_start > time_end)
		return ERROR_READ;
	else
		return num_smpls;
}

ssize_t smpl_buf::read(void *buf, size_t len, uhd::time_spec_t ts)
{
	return read(buf, len, convert_time(ts, clk_rt));
}

ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp)
{
	// Check for valid write
	if ((len == 0) || (len >= buf_len))
		return ERROR_WRITE;
	if ((timestamp + len) <= time_end)
		return ERROR_TIMESTAMP;

	// Starting index
	size_t write_start = (data_start + (timestamp - time_start)) % buf_len;

	// Write it
	if ((write_start + len) < buf_len) {
		size_t numBytes = len * 2 * sizeof(short);
		memcpy(data + write_start, buf, numBytes);
	} else {
		size_t first_cp = (buf_len - write_start) * 2 * sizeof(short);
		size_t second_cp = len * 2 * sizeof(short) - first_cp;

		memcpy(data + write_start, buf, first_cp);
		memcpy(data, (char*) buf + first_cp, second_cp);
	}

	data_end = (write_start + len) % buf_len;
	time_end = timestamp + len;

	if (((write_start + len) > buf_len) && (data_end > data_start))
		return ERROR_OVERFLOW;
	else if (time_end <= time_start)
		return ERROR_WRITE;
	else
		return len;
}

ssize_t smpl_buf::write(void *buf, size_t len, uhd::time_spec_t ts)
{
	return write(buf, len, convert_time(ts, clk_rt));
}

std::string smpl_buf::str_status() const
{
	std::ostringstream ost("Sample buffer: ");

	ost << "length = " << buf_len;
	ost << ", time_start = " << time_start;
	ost << ", time_end = " << time_end;
	ost << ", data_start = " << data_start;
	ost << ", data_end = " << data_end;

	return ost.str();
}

std::string smpl_buf::str_code(ssize_t code)
{
	switch (code) {
	case ERROR_TIMESTAMP:
		return "Sample buffer: Requested timestamp is not valid";
	case ERROR_READ:
		return "Sample buffer: Read error";
	case ERROR_WRITE:
		return "Sample buffer: Write error";
	case ERROR_OVERFLOW:
		return "Sample buffer: Overrun";
	default:
		return "Sample buffer: Unknown error";
	}
}

RadioDevice *RadioDevice::make(double smpl_rt, bool skip_rx)
{
	return new uhd_device(smpl_rt, skip_rx);
}
