/*
 * libiio - Library for interfacing industrial I/O (IIO) devices
 *
 * Copyright (C) 2016 Analog Devices, Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 */

#include "../debug.h"
#include "../iio-private.h"
#include "ops.h"
#include "thread-pool.h"

#include <fcntl.h>
#include <linux/usb/functionfs.h>
#include <stdint.h>
#include <string.h>

/* u8"IIO" for non-c11 compilers */
#define NAME "\x0049\x0049\x004F"

#define LE32(x) ((__BYTE_ORDER != __BIG_ENDIAN) ? (x) : __bswap_constant_32(x))
#define LE16(x) ((__BYTE_ORDER != __BIG_ENDIAN) ? (x) : __bswap_constant_16(x))

#define IIO_USD_CMD_RESET_PIPES 0
#define IIO_USD_CMD_OPEN_PIPE 1
#define IIO_USD_CMD_CLOSE_PIPE 2


struct usb_ffs_header {
	struct usb_functionfs_descs_head_v2 header;
	uint32_t nb_fs, nb_hs, nb_ss;
} __attribute__((packed));

struct usb_ffs_strings {
	struct usb_functionfs_strings_head head;
	uint16_t lang;
	const char string[sizeof(NAME)];
} __attribute__((packed));

struct usbd_pdata {
	struct iio_context *ctx;
	char *ffs;
	int ep0_fd;
	bool debug, use_aio;
	struct thread_pool **pool;
	unsigned int nb_pipes;
};

struct usbd_client_pdata {
	struct usbd_pdata *pdata;
	int ep_in, ep_out;
};

static const struct usb_ffs_strings ffs_strings = {
	.head = {
		.magic = LE32(FUNCTIONFS_STRINGS_MAGIC),
		.length = LE32(sizeof(ffs_strings)),
		.str_count = LE32(1),
		.lang_count = LE32(1),
	},

	.lang = LE16(0x409),
	.string = NAME,
};

static void usbd_client_thread(struct thread_pool *pool, void *d)
{
	struct usbd_client_pdata *pdata = d;

	interpreter(pdata->pdata->ctx, pdata->ep_in, pdata->ep_out,
			pdata->pdata->debug, false,
			pdata->pdata->use_aio, pool);

	close(pdata->ep_in);
	close(pdata->ep_out);
	free(pdata);
}

static int usb_open_pipe(struct usbd_pdata *pdata, unsigned int pipe_id)
{
	struct usbd_client_pdata *cpdata;
	char buf[256];
	int err;

	if (pipe_id >= pdata->nb_pipes)
		return -EINVAL;

	cpdata = malloc(sizeof(*cpdata));
	if (!pdata)
		return -ENOMEM;

	/* Either we open this pipe for the first time, or it was closed before.
	 * In that case we called thread_pool_stop() without waiting for all the
	 * threads to finish. We do that here. Since the running thread might still
	 * have a open handle to the endpoints make sure that they have exited
	 * before opening the endpoints again. */
	thread_pool_stop_and_wait(pdata->pool[pipe_id]);

	snprintf(buf, sizeof(buf), "%s/ep%u", pdata->ffs, pipe_id * 2 + 1);
	cpdata->ep_out = open(buf, O_WRONLY);
	if (cpdata->ep_out < 0) {
		err = -errno;
		goto err_free_cpdata;
	}

	snprintf(buf, sizeof(buf), "%s/ep%u", pdata->ffs, pipe_id * 2 + 2);
	cpdata->ep_in = open(buf, O_RDONLY);
	if (cpdata->ep_in < 0) {
		err = -errno;
		goto err_close_ep_out;
	}

	cpdata->pdata = pdata;

	err = thread_pool_add_thread(pdata->pool[pipe_id],
			usbd_client_thread, cpdata, "usbd_client_thd");
	if (!err)
		return 0;

	close(cpdata->ep_in);
err_close_ep_out:
	close(cpdata->ep_out);
err_free_cpdata:
	free(cpdata);
	return err;
}

static int usb_close_pipe(struct usbd_pdata *pdata, unsigned int pipe_id)
{
	if (pipe_id >= pdata->nb_pipes)
		return -EINVAL;

	thread_pool_stop(pdata->pool[pipe_id]);
	return 0;
}

static void usb_close_pipes(struct usbd_pdata *pdata)
{
	unsigned int i;

	for (i = 0; i < pdata->nb_pipes; i++)
		usb_close_pipe(pdata, i);
}

static int handle_event(struct usbd_pdata *pdata,
		const struct usb_functionfs_event *event)
{
	int ret = 0;

	if (event->type == FUNCTIONFS_SETUP) {
		const struct usb_ctrlrequest *req = &event->u.setup;

		switch (req->bRequest) {
		case IIO_USD_CMD_RESET_PIPES:
			usb_close_pipes(pdata);
			break;
		case IIO_USD_CMD_OPEN_PIPE:
			ret = usb_open_pipe(pdata, le16toh(req->wValue));
			break;
		case IIO_USD_CMD_CLOSE_PIPE:
			ret = usb_close_pipe(pdata, le16toh(req->wValue));
			break;
		}
	}

	return ret;
}

static void usbd_main(struct thread_pool *pool, void *d)
{
	int stop_fd = thread_pool_get_poll_fd(pool);
	struct usbd_pdata *pdata = d;
	unsigned int i;

	for (;;) {
		struct usb_functionfs_event event;
		struct pollfd pfd[2];
		int ret;

		pfd[0].fd = pdata->ep0_fd;
		pfd[0].events = POLLIN;
		pfd[0].revents = 0;
		pfd[1].fd = stop_fd;
		pfd[1].events = POLLIN;
		pfd[1].revents = 0;

		poll_nointr(pfd, 2);

		if (pfd[1].revents & POLLIN) /* STOP event */
			break;

		if (!(pfd[0].revents & POLLIN)) /* Should never happen. */
			continue;

		ret = read(pdata->ep0_fd, &event, sizeof(event));
		if (ret != sizeof(event)) {
			WARNING("Short read!\n");
			continue;
		}

		ret = handle_event(pdata, &event);
		if (ret) {
			ERROR("Unable to handle event: %i\n", ret);
			break;
		}

		/* Clear out the errors on ep0 when we close endpoints */
		ret = read(pdata->ep0_fd, NULL, 0);
	}

	for (i = 0; i < pdata->nb_pipes; i++) {
		thread_pool_stop_and_wait(pdata->pool[i]);
		thread_pool_destroy(pdata->pool[i]);
	}

	close(pdata->ep0_fd);
	free(pdata->ffs);
	free(pdata->pool);
	free(pdata);
}

static struct usb_ffs_header * create_header(
		unsigned int nb_pipes, uint32_t size)
{
	/* Packet sizes for USB high-speed, full-speed, super-speed */
	const unsigned int packet_sizes[3] = { 64, 512, 1024, };
	struct usb_ffs_header *hdr;
	unsigned int i, pipe_id;
	uintptr_t ptr;

	hdr = zalloc(size);
	if (!hdr) {
		errno = ENOMEM;
		return NULL;
	}

	hdr->header.magic = LE32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
	hdr->header.length = htole32(size);
	hdr->header.flags = LE32(FUNCTIONFS_HAS_FS_DESC |
			FUNCTIONFS_HAS_HS_DESC |
			FUNCTIONFS_HAS_SS_DESC);

	hdr->nb_fs = htole32(nb_pipes * 2 + 1);
	hdr->nb_hs = htole32(nb_pipes * 2 + 1);
	hdr->nb_ss = htole32(nb_pipes * 4 + 1);

	ptr = ((uintptr_t) hdr) + sizeof(*hdr);

	for (i = 0; i < 3; i++) {
		struct usb_interface_descriptor *desc =
			(struct usb_interface_descriptor *) ptr;
		struct usb_endpoint_descriptor_no_audio *ep;
		struct usb_ss_ep_comp_descriptor *comp;

		desc->bLength = sizeof(*desc);
		desc->bDescriptorType = USB_DT_INTERFACE;
		desc->bNumEndpoints = nb_pipes * 2;
		desc->bInterfaceClass = USB_CLASS_COMM;
		desc->iInterface = 1;

		ep = (struct usb_endpoint_descriptor_no_audio *)
			(ptr + sizeof(*desc));

		for (pipe_id = 0; pipe_id < nb_pipes; pipe_id++) {
			ep->bLength = sizeof(*ep);
			ep->bDescriptorType = USB_DT_ENDPOINT;
			ep->bEndpointAddress = (pipe_id + 1) | USB_DIR_IN;
			ep->bmAttributes = USB_ENDPOINT_XFER_BULK;
			ep->wMaxPacketSize = htole16(packet_sizes[i]);
			ep++;

			if (i == 2) {
				comp = (struct usb_ss_ep_comp_descriptor *) ep;
				comp->bLength = USB_DT_SS_EP_COMP_SIZE;
				comp->bDescriptorType = USB_DT_SS_ENDPOINT_COMP;
				comp++;
				ep = (struct usb_endpoint_descriptor_no_audio *) comp;
			}

			ep->bLength = sizeof(*ep);
			ep->bDescriptorType = USB_DT_ENDPOINT;
			ep->bEndpointAddress = (pipe_id + 1) | USB_DIR_OUT;
			ep->bmAttributes = USB_ENDPOINT_XFER_BULK;
			ep->wMaxPacketSize = htole16(packet_sizes[i]);
			ep++;

			if (i == 2) {
				comp = (struct usb_ss_ep_comp_descriptor *) ep;
				comp->bLength = USB_DT_SS_EP_COMP_SIZE;
				comp->bDescriptorType = USB_DT_SS_ENDPOINT_COMP;
				comp++;
				ep = (struct usb_endpoint_descriptor_no_audio *) comp;
			}
		}

		ptr += sizeof(*desc) + nb_pipes * 2 * sizeof(*ep);
	}

	return hdr;
}

static int write_header(int fd, unsigned int nb_pipes)
{
	uint32_t size = sizeof(struct usb_ffs_header) +
		3 * sizeof(struct usb_interface_descriptor) +
		6 * nb_pipes * sizeof(struct usb_endpoint_descriptor_no_audio) +
		2 * nb_pipes * sizeof(struct usb_ss_ep_comp_descriptor);
	struct usb_ffs_header *hdr;
	int ret;

	hdr = create_header(nb_pipes, size);
	if (!hdr)
		return -errno;

	ret = write(fd, hdr, size);
	free(hdr);
	if (ret < 0)
		return -errno;

	ret = write(fd, &ffs_strings, sizeof(ffs_strings));
	if (ret < 0)
		return -errno;

	return 0;
}

int start_usb_daemon(struct iio_context *ctx, const char *ffs,
		bool debug, bool use_aio, unsigned int nb_pipes,
		struct thread_pool *pool)
{
	struct usbd_pdata *pdata;
	unsigned int i;
	char buf[256];
	int ret;

	pdata = zalloc(sizeof(*pdata));
	if (!pdata)
		return -ENOMEM;

	pdata->nb_pipes = nb_pipes;

	pdata->pool = calloc(nb_pipes, sizeof(*pdata->pool));
	if (!pdata->pool) {
		ret = -ENOMEM;
		goto err_free_pdata;
	}

	pdata->ffs = strdup(ffs);
	if (!pdata->ffs) {
		ret = -ENOMEM;
		goto err_free_pdata_pool;
	}

	snprintf(buf, sizeof(buf), "%s/ep0", ffs);

	pdata->ep0_fd = open(buf, O_RDWR);
	if (pdata->ep0_fd < 0) {
		ret = -errno;
		goto err_free_ffs;
	}

	ret = write_header(pdata->ep0_fd, nb_pipes);
	if (ret < 0)
		goto err_close_ep0;

	for (i = 0; i < nb_pipes; i++) {
		pdata->pool[i] = thread_pool_new();
		if (!pdata->pool[i]) {
			ret = -errno;
			goto err_free_pools;
		}
	}

	pdata->ctx = ctx;
	pdata->debug = debug;
	pdata->use_aio = use_aio;

	ret = thread_pool_add_thread(pool, usbd_main, pdata, "usbd_main_thd");
	if (!ret)
		return 0;

err_free_pools:
	/* If we get here, usbd_main was not started, so the pools can be
	 * destroyed directly */
	for (i = 0; i < nb_pipes; i++) {
		if (pdata->pool[i])
			thread_pool_destroy(pdata->pool[i]);
	}
err_close_ep0:
	close(pdata->ep0_fd);
err_free_ffs:
	free(pdata->ffs);
err_free_pdata_pool:
	free(pdata->pool);
err_free_pdata:
	free(pdata);
	return ret;
}
