/* simtrace - main program for the host PC
 *
 * (C) 2010-2016 by Harald Welte <hwelte@hmw-consulting.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 
 *  as published by the Free Software Foundation
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#define _GNU_SOURCE
#include <getopt.h>
#include <poll.h>

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <libusb.h>

#include "simtrace.h"
#include "cardemu_prot.h"
#include "apdu_dispatch.h"
#include "simtrace2-discovery.h"

#include <osmocom/core/utils.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/select.h>

struct libusb_device_handle *g_devh;
static struct sockaddr_in g_sa_remote;
static struct osmo_fd g_udp_ofd;

static void print_welcome(void)
{
	printf("usb2udp - UDP/IP forwarding of SIMtrace card emulation\n"
	       "(C) 2016 by Harald Welte <laforge@gnumonks.org>\n\n");
}

static void print_help(void)
{
	printf( "\t-h\t--help\n"
		"\t-i\t--interface <0-255>\n"
		"\n"
		);
}

struct ep_buf {
	uint8_t ep;
	uint8_t buf[1024];
	struct libusb_transfer *xfer;
};
static struct ep_buf g_buf_in;
static struct ep_buf g_buf_out;

static void usb_in_xfer_cb(struct libusb_transfer *xfer)
{
	int rc;

	printf("xfer_cb(ep=%02x): status=%d, flags=0x%x, type=%u, len=%u, act_len=%u\n",
		xfer->endpoint, xfer->status, xfer->flags, xfer->type, xfer->length, xfer->actual_length);
	switch (xfer->status) {
	case LIBUSB_TRANSFER_COMPLETED:
		if (xfer->endpoint == g_buf_in.ep) {
			/* process the data */
			printf("read %d bytes from SIMTRACE, forwarding to UDP\n", xfer->actual_length);
			rc = sendto(g_udp_ofd.fd, xfer->buffer, xfer->actual_length, 0, (struct sockaddr *)&g_sa_remote, sizeof(g_sa_remote));
			if (rc <= 0) {
				fprintf(stderr, "error writing to UDP\n");
			}
			/* and re-submit the URB */
			libusb_submit_transfer(xfer);
		} else if (xfer->endpoint == g_buf_out.ep) {
			/* re-enable reading from the UDP side */
			g_udp_ofd.when |= BSC_FD_READ;
		}
		break;
	default:
		fprintf(stderr, "xfer_cb(ERROR '%s')\n", osmo_hexdump_nospc(xfer->buffer, xfer->actual_length));
		break;
	}
}

static void init_ep_buf(struct ep_buf *epb)
{
	if (!epb->xfer)
		epb->xfer = libusb_alloc_transfer(0);

	epb->xfer->flags = 0;

	libusb_fill_bulk_transfer(epb->xfer, g_devh, epb->ep, epb->buf, sizeof(epb->buf), usb_in_xfer_cb, NULL, 0);
}

/***********************************************************************
 * libosmocore main loop integration of libusb async I/O
 ***********************************************************************/

static int g_libusb_pending = 0;

static int ofd_libusb_cb(struct osmo_fd *ofd, unsigned int what)
{
	/* FIXME */
	g_libusb_pending = 1;

	return 0;
}

/* call-back when libusb adds a FD */
static void libusb_fd_added_cb(int fd, short events, void *user_data)
{
	struct osmo_fd *ofd = talloc_zero(NULL, struct osmo_fd);

	printf("%s(%u, %x)\n", __func__, fd, events);

	ofd->fd = fd;
	ofd->cb = &ofd_libusb_cb;
	if (events & POLLIN)
		ofd->when |= BSC_FD_READ;
	if (events & POLLOUT)
		ofd->when |= BSC_FD_WRITE;

	osmo_fd_register(ofd);
}

/* call-back when libusb removes a FD */
static void libusb_fd_removed_cb(int fd, void *user_data)
{
	struct osmo_fd *ofd;

	printf("%s(%u)\n", __func__, fd);
#if 0
	/* FIXME: This needs new export in libosmocore! */
	ofd = osmo_fd_get_by_fd(fd);

	if (ofd) {
		osmo_fd_unregister(ofd);
		talloc_free(ofd);
	}
#endif
}

/* call-back when the UDP socket is readable */
static int ofd_udp_cb(struct osmo_fd *ofd, unsigned int what)
{
	int rc;
	int addrlen = sizeof(g_sa_remote);

	rc = recvfrom(ofd->fd, g_buf_out.buf, sizeof(g_buf_out.buf), 0,
			(struct sockaddr *)&g_sa_remote, &addrlen);
	if (rc <= 0) {
		fprintf(stderr, "error reading from UDP\n");
		return 0;
	}
	printf("read %d bytes from UDP, forwarding to SIMTRACE\n", rc);
	g_buf_out.xfer->length = rc;

	/* disable further READ interest for the UDP socket */
	ofd->when &= ~BSC_FD_READ;

	/* submit the URB on the OUT end point */
	libusb_submit_transfer(g_buf_out.xfer);

	return 0;
}

static void run_mainloop(void)
{
	int rc;

	printf("Entering main loop\n");

	while (1) {
		osmo_select_main(0);
		if (g_libusb_pending) {
			struct timeval tv;
			memset(&tv, 0, sizeof(tv));
			rc = libusb_handle_events_timeout_completed(NULL, &tv, NULL);
			if (rc != 0) {
				fprintf(stderr, "handle_events_timeout_completed == %d\n", rc);
				break;
			}
		}
	}
}

int main(int argc, char **argv)
{
	int rc;
	int c, ret = 1;
	char *remote_host = NULL;
	int local_udp_port = 52342;
	unsigned int if_num = 0;

	print_welcome();

	while (1) {
		int option_index = 0;
		static const struct option opts[] = {
			{ "udp-port", 1, 0, 'u' },
			{ "interface", 1, 0, 'I' },
			{ "help", 0, 0, 'h' },
			{ NULL, 0, 0, 0 }
		};

		c = getopt_long(argc, argv, "u:I:h", opts, &option_index);
		if (c == -1)
			break;
		switch (c) {
		case 'u':
			local_udp_port = atoi(optarg);
			break;
		case 'I':
			if_num = atoi(optarg);
			break;
		case 'h':
			print_help();
			exit(0);
			break;
		}
	}

	rc = libusb_init(NULL);
	if (rc < 0) {
		fprintf(stderr, "libusb initialization failed\n");
		goto close_exit;
	}

	libusb_set_pollfd_notifiers(NULL, &libusb_fd_added_cb, &libusb_fd_removed_cb, NULL);

	g_devh = libusb_open_device_with_vid_pid(NULL, SIMTRACE_USB_VENDOR, SIMTRACE_USB_PRODUCT);
	if (!g_devh) {
		fprintf(stderr, "can't open USB device\n");
		goto close_exit;
	}

	rc = libusb_claim_interface(g_devh, if_num);
	if (rc < 0) {
		fprintf(stderr, "can't claim interface %u; rc=%d\n", if_num, rc);
		goto close_exit;
	}

	/* open UDP socket, register with select handling and mark it
	 * readable */
	g_udp_ofd.cb = ofd_udp_cb;
	osmo_sock_init_ofd(&g_udp_ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, local_udp_port + if_num, OSMO_SOCK_F_BIND);

	rc = get_usb_ep_addrs(g_devh, if_num, &g_buf_out.ep, &g_buf_in.ep, NULL);
	if (rc < 0) {
		fprintf(stderr, "couldn't find enpdoint addresses; rc=%d\n", rc);
		goto close_exit;
	}
	/* initialize USB buffers / transfers */
	init_ep_buf(&g_buf_out);
	init_ep_buf(&g_buf_in);

	/* submit the first transfer for the IN endpoint */
	libusb_submit_transfer(g_buf_in.xfer);

	run_mainloop();

	ret = 0;

	libusb_release_interface(g_devh, 0);
close_exit:
	if (g_devh)
		libusb_close(g_devh);

release_exit:
	libusb_exit(NULL);
	return ret;
}
