/*
 * This file is part of the libsigrok project.
 *
 * Copyright 2014 Google, Inc
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "protocol.h"

#include <stdint.h>
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <libusb.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>
#include "libsigrok.h"
#include "libsigrok-internal.h"

#define COMMAND_START_ACQUISITION	1
#define COMMAND_ABORT_ACQUISITION_ASYNC	2
#define COMMAND_ABORT_ACQUISITION_SYNC	0x7d

int sniffer_sample_header_size; /* set in api.c, can be 4 or 8 */

static int do_console_command(const struct sr_dev_inst *sdi,
			      const uint8_t *command, uint8_t cmd_len,
			      uint8_t *reply, uint8_t reply_len)
{
	uint8_t buf[64];
	struct sr_usb_dev_inst *usb;
	int ret, xfer;

	/* Temporary HACK */
	return SR_OK;

	usb = sdi->conn;

	if (cmd_len < 1 || cmd_len > 64 || reply_len > 64 ||
	    command == NULL || (reply_len > 0 && reply == NULL))
		return SR_ERR_ARG;

	ret = libusb_bulk_transfer(usb->devhdl, 2, buf, cmd_len, &xfer, 1000);
	if (ret != 0) {
		sr_dbg("Failed to send console command 0x%02x: %s.",
		       command[0], libusb_error_name(ret));
		return SR_ERR;
	}
	if (xfer != cmd_len) {
		sr_dbg("Failed to send console command 0x%02x: incorrect length "
		       "%d != %d.", xfer, cmd_len);
		return SR_ERR;
	}

	if (reply_len == 0)
		return SR_OK;

	ret = libusb_bulk_transfer(usb->devhdl, 0x80 | 1, buf, reply_len,
				   &xfer, 1000);
	if (ret != 0) {
		sr_dbg("Failed to receive reply to console command 0x%02x: %s.",
		       command[0], libusb_error_name(ret));
		return SR_ERR;
	}
	if (xfer != reply_len) {
		sr_dbg("Failed to receive reply to console command 0x%02x: "
		       "incorrect length %d != %d.", xfer, reply_len);
		return SR_ERR;
	}

	return SR_OK;
}

SR_PRIV int twinkie_start_acquisition(const struct sr_dev_inst *sdi)
{
	static const uint8_t command[1] = {
		COMMAND_START_ACQUISITION,
	};
	int ret;

	if ((ret = do_console_command(sdi, command, 1, NULL, 0)) != SR_OK)
		return ret;

	return SR_OK;
}

SR_PRIV int twinkie_init_device(const struct sr_dev_inst *sdi)
{
	(void)sdi;

	return SR_OK;
}

static void finish_acquisition(struct dev_context *devc)
{
	struct sr_datafeed_packet packet;
	struct sr_dev_inst *sdi = devc->cb_data;

	/* Terminate session. */
	packet.type = SR_DF_END;
	sr_session_send(devc->cb_data, &packet);

	/* Remove fds from polling. */
	usb_source_remove(sdi->session, devc->ctx);

	devc->num_transfers = 0;
	g_free(devc->transfers);
	g_free(devc->convbuffer);
}

static void free_transfer(struct libusb_transfer *transfer)
{
	struct dev_context *devc;
	unsigned int i;

	devc = transfer->user_data;

	g_free(transfer->buffer);
	transfer->buffer = NULL;
	libusb_free_transfer(transfer);

	for (i = 0; i < devc->num_transfers; i++) {
		if (devc->transfers[i] == transfer) {
			devc->transfers[i] = NULL;
			break;
		}
	}

	devc->submitted_transfers--;
	if (devc->submitted_transfers == 0)
		finish_acquisition(devc);
}

static void export_samples(struct dev_context *devc, int cnt)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;

	/* export the received data */
	packet.type = SR_DF_LOGIC;
	packet.payload = &logic;
	if (devc->limit_samples &&
	    cnt > devc->limit_samples - devc->sent_samples)
		cnt = devc->limit_samples - devc->sent_samples;
	logic.length = cnt * SAMPLE_UNIT_SIZE;
	logic.unitsize = SAMPLE_UNIT_SIZE;
	logic.data = devc->convbuffer;
	sr_session_send(devc->cb_data, &packet);
	devc->sent_samples += cnt;
}

static void set_vbus_voltage_bits(uint8_t *vbus_dest, uint16_t vbus_voltage, int16_t offset)
{
	/*
	 * Similar to RS232 encoding method. Encoding Format:
	 * IDLE: 0
	 * Start: 1
	 * Data: Value[15:0], TimeStamp[15:0]
	 * Stop: 0
	 */
	int i = 0;
	/* the offset passed in is in us, and can be overflowed */
	int offset_ms = offset/1000;
	if (offset_ms > 0) /* convert overflowed value to the correct one */
		offset_ms = -65 + offset_ms;
	*vbus_dest |= 1<<2; /* start bit */
	for (i = 0; i < 16; i ++)
		*(vbus_dest + 1 + i) |= (((vbus_voltage >> i) & 1) << 2);
	for (i = 0; i < 16; i ++)
		*(vbus_dest + 17 + i) |= (((offset_ms >> i) & 1) << 2);
}

static void set_vbus_current_bits(uint8_t *vbus_dest, int16_t vbus_current, int16_t offset)
{
	int i = 0;
	int offset_ms = offset/1000;
	*vbus_dest |= 1<<3; /* start bit */
	if (offset_ms > 0)
		offset_ms = -65 + offset_ms;
	for (i = 0; i < 16; i ++)
		*(vbus_dest + 1 + i) |= (((vbus_current >> i) & 1) << 3);
	for (i = 0; i < 16; i ++)
		*(vbus_dest + 17 + i) |= (((offset_ms >> i) & 1) << 3);
}

uint16_t vbus_voltage_previous = 0;
int16_t vbus_current_previous = 0;

static void expand_sample_data(struct dev_context *devc,
			       const uint8_t *src, size_t srccnt)
{
	int i, f;
	size_t b;
	size_t rdy_samples, left_samples;
	int frames = srccnt / SNIFFER_SAMPLE_PACKET_SIZE;

	int sniffer_sample_payload_size = (SNIFFER_SAMPLE_PACKET_SIZE - sniffer_sample_header_size);
	for (f = 0; f < frames; f++) {
		int ch = (src[1] >> 4) & 3; /* samples channel number */
		int bit = 1 << ch; /* channel bit mask */
		struct cc_context *cc = devc->cc + ch;
		uint8_t *dest = devc->convbuffer + cc->idx;
		uint8_t *vbus_dest;
		if (ch >= 2) /* only acquires CCx channels */
			continue;

		int vbus_voltage_set = 0; /* vbus set or not in this frame? 0: not; 1: set */
		int vbus_current_set = 0;

		/* TODO: check timestamp, overflow, sequence number */
		/* need to calculate first; otherwise, will not get the correct value since src is updated */
		uint16_t vbus_voltage = ((src[5] << 8 )| src[4]);
		int16_t vbus_current = ((src[5] << 8 )| src[4]); /* may be voltage, may be current. */
		int16_t vbus_offset = ((src[7] << 8 )| src[6]); /* may be the offset for voltage, or current.*/

		/* skip header, go to edges data */
		src+= sniffer_sample_header_size;
		for (i = 0; i < sniffer_sample_payload_size; i++,src++)
			if (*src == cc->prev_src) {
				cc->rollbacks++;
			} else {
				uint8_t diff = *src - cc->prev_src;
				int fixup = cc->rollbacks && (((int)*src < (int)cc->prev_src) || (*src == 0xff));
				size_t total = (fixup ? cc->rollbacks - 1 : cc->rollbacks) * 256 + diff;

				if (total + cc->idx > devc->convbuffer_size) {
					sr_warn("overflow %d+%d/%d\n",
						cc->idx, total,
						devc->convbuffer_size);
					/* reset current decoding */
					cc->rollbacks = 0;
					break;
				}

				vbus_dest = dest;
				/* insert bits in the buffer */
				if (cc->level)
					for (b = 0 ; b < total ; b++, dest++)
						*dest |= bit;
				else
					dest += total;

#ifdef CONFIG_USBC_SNIFFER_HEADER_V2
				if (ch == 0) { /* cc1 header carries vbus voltage*/
					if (!vbus_voltage_set) {
						set_vbus_voltage_bits(vbus_dest, vbus_voltage, vbus_offset);
						vbus_voltage_set = 1; /* after that, label vbus_voltage_set to true */
						vbus_voltage_previous = vbus_voltage;
					}
				}
				else { /* cc2 header carries vbus current*/
					if (!vbus_current_set) {
						set_vbus_current_bits(vbus_dest, vbus_current, vbus_offset);
						vbus_current_set = 1;
						vbus_current_previous = vbus_current;
					}
				}
#endif

				cc->idx += total;
				/* flip level on the next edge */
				cc->level = ~cc->level;

				cc->rollbacks = 0;
				cc->prev_src = *src;
			}

		/* expand repeated rollbacks */
		if (cc->rollbacks > 1) {
			size_t total = 256 * (cc->rollbacks - 1);
			if (total + cc->idx > devc->convbuffer_size) {
				sr_warn("overflow %d+%d/%d\n",
					cc->idx, total, devc->convbuffer_size);
				/* reset current decoding */
				total = 0;
			}
			vbus_dest = dest;
			/* insert bits in the buffer */
			if (cc->level)
				for (b = 0 ; b < total ; b++, dest++)
					*dest |= bit ;
			else
				dest += total;

#ifdef CONFIG_USBC_SNIFFER_HEADER_V2
			if (ch == 0) {
				if (!vbus_voltage_set) {
					set_vbus_voltage_bits(vbus_dest, vbus_voltage, vbus_offset);
					vbus_voltage_set = 1;
					vbus_voltage_previous = vbus_voltage;
				}
			}
			else {
				if (!vbus_current_set) {
					set_vbus_current_bits(vbus_dest, vbus_current, vbus_offset);
					vbus_current_set = 1;
					vbus_current_previous = vbus_current;
				}
			}
#endif
			cc->idx += total;
			cc->rollbacks = 1;
		}
	}

	/* samples ready to be pushed (with both channels) */
	rdy_samples = MIN(devc->cc[0].idx, devc->cc[1].idx);
	left_samples = MAX(devc->cc[0].idx, devc->cc[1].idx) - rdy_samples;
	/* skip empty transfer */
	if (rdy_samples == 0)
		return;

	export_samples(devc, rdy_samples);

	/* clean up what we have sent */
	memmove(devc->convbuffer, devc->convbuffer + rdy_samples, left_samples * SAMPLE_UNIT_SIZE);
	memset(devc->convbuffer + left_samples, 0, rdy_samples * SAMPLE_UNIT_SIZE);
	devc->cc[0].idx -= rdy_samples;
	devc->cc[1].idx -= rdy_samples;
}

SR_PRIV void twinkie_receive_transfer(struct libusb_transfer *transfer)
{
	gboolean packet_has_error = FALSE;
	struct dev_context *devc;

	devc = transfer->user_data;

	/*
	 * If acquisition has already ended, just free any queued up
	 * transfer that come in.
	 */
	if (devc->sent_samples < 0) {
		free_transfer(transfer);
		return;
	}

	if (transfer->status || transfer->actual_length)
		sr_info("receive_transfer(): status %d received %d bytes.",
			transfer->status, transfer->actual_length);

	switch (transfer->status) {
	case LIBUSB_TRANSFER_NO_DEVICE:
		devc->sent_samples = -2;
		free_transfer(transfer);
		return;
	case LIBUSB_TRANSFER_COMPLETED:
	case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */
		break;
	default:
		packet_has_error = TRUE;
		break;
	}

	if (transfer->actual_length % SNIFFER_SAMPLE_PACKET_SIZE) {
		sr_err("Bad USB packet size.");
		packet_has_error = TRUE;
	}

	if (transfer->actual_length == 0 || packet_has_error)
		goto resubmit;

	/* decode received edges */
	expand_sample_data(devc, transfer->buffer, transfer->actual_length);

	if (devc->limit_samples &&
			(uint64_t)devc->sent_samples >= devc->limit_samples) {
		devc->sent_samples = -2;
		free_transfer(transfer);
		return;
	}
resubmit:
	if (libusb_submit_transfer(transfer) != LIBUSB_SUCCESS)
		free_transfer(transfer);
}
