/* libosmocore integration with libusb-1.0
 *
 * (C) 2019-2019 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <poll.h>

#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/select.h>
#include <osmocom/core/talloc.h>

#include <libusb.h>

#include <osmocom/usb/libusb.h>

/***********************************************************************
 * logging integration
 ***********************************************************************/

#define DLUSB	DLINP

#ifdef LIBUSB_LOG_CB_CONTEXT /* introduced in 1.0.23 */
static const int usb2logl[] = {
	[LIBUSB_LOG_LEVEL_NONE] = LOGL_FATAL,
	[LIBUSB_LOG_LEVEL_ERROR] = LOGL_ERROR,
	[LIBUSB_LOG_LEVEL_WARNING] = LOGL_NOTICE,
	[LIBUSB_LOG_LEVEL_INFO] = LOGL_INFO,
	[LIBUSB_LOG_LEVEL_DEBUG] = LOGL_DEBUG,
};

/* called by libusb if it wants to log something */
static void libosmo_usb_log_cb(libusb_context *luctx, enum libusb_log_level level_usb, const char *str)
{
	int level = LOGL_NOTICE;

	if (level_usb < ARRAY_SIZE(usb2logl))
		level = usb2logl[level_usb];

	LOGP(DLUSB, level, "%s", str);
}
#endif /* LIBUSB_LOG_CB_CONTEXT */

/***********************************************************************
 * select loop integration
 ***********************************************************************/

static int osmo_usb_fd_cb(struct osmo_fd *ofd, unsigned int what)
{
	libusb_context *luctx = ofd->data;

	/* we assume that we're running Linux v2.6.27 with timerfd support here
	 * and hence don't have to perform manual timeout handling.  See
	 * "Notes on time-based events" at
	 * http://libusb.sourceforge.net/api-1.0/group__libusb__poll.html */
	struct timeval zero_tv = { 0, 0 };
	libusb_handle_events_timeout(luctx, &zero_tv);

	return 0;
}

/* called by libusb if it wants to add a file-descriptor */
static void osmo_usb_added_cb(int fd, short events, void *user_data)
{
	struct osmo_fd *ofd = talloc_zero(OTC_GLOBAL, struct osmo_fd);
	libusb_context *luctx = user_data;
	unsigned int when = 0;

	if (events & POLLIN)
		when |= OSMO_FD_READ;
	if (events & POLLOUT)
		when |= OSMO_FD_WRITE;

	osmo_fd_setup(ofd, fd, when, osmo_usb_fd_cb, luctx, 0);
	osmo_fd_register(ofd);
}

/* called by libusb if it wants to remove a file-descriptor */
static void osmo_usb_removed_cb(int fd, void *user_data)
{
	struct osmo_fd *ofd = osmo_fd_get_by_fd(fd);
	if (!fd)
		return;
	osmo_fd_unregister(ofd);
	talloc_free(ofd);
}

/***********************************************************************
 * utility functions
 ***********************************************************************/

/*! obtain the string representation of the USB device path of given device.
 *  \param[out] buf Output string buffer
 *  \param[in] bufsize Size of output string buffer in bytes
 *  \param[in] dev USB device whose bus path we want to obtain
 *  \returns pointer to 'buf' in case of success; NULL in case of error */
char *osmo_libusb_dev_get_path_buf(char *buf, size_t bufsize, libusb_device *dev)
{
#if (defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102) || \
    (defined(LIBUSBX_API_VERSION) && LIBUSBX_API_VERSION >= 0x01000102)
	struct osmo_strbuf sb = { .buf = buf, .len = bufsize };
	uint8_t path[8];
	int r,j;
	r = libusb_get_port_numbers(dev, path, sizeof(path));
	if (r > 0) {
		OSMO_STRBUF_PRINTF(sb, "%d-%d", libusb_get_bus_number(dev), path[0]);
		for (j = 1; j < r; j++){
			OSMO_STRBUF_PRINTF(sb, ".%d", path[j]);
		}
	}
	return buf;
#else
# warning "libusb too old - building without USB path support!"
	return NULL;
#endif
}

/*! obtain the string representation of the USB device path of given device.
 *  \param[in] talloc context from which to dynamically allocate output string buffer
 *  \param[in] dev USB device whose bus path we want to obtain
 *  \returns pointer to 'buf' in case of success; NULL in case of error */
char *osmo_libusb_dev_get_path_c(void *ctx, libusb_device *dev)
{
	char *buf = talloc_zero_size(ctx, USB_MAX_PATH_LEN);
	if (!buf)
		return NULL;
	return osmo_libusb_dev_get_path_buf(buf, USB_MAX_PATH_LEN, dev);
}

static int match_dev_id(const struct libusb_device_descriptor *desc, const struct dev_id *id)
{
	if ((desc->idVendor == id->vendor_id) && (desc->idProduct == id->product_id))
		return 1;
	return 0;
}

static int match_dev_ids(const struct libusb_device_descriptor *desc, const struct dev_id *ids)
{
	const struct dev_id *id;

	for (id = ids; id->vendor_id || id->product_id; id++) {
		if (match_dev_id(desc, id))
			return 1;
	}
	return 0;
}

/*! Find USB devices matching the specified list of USB VendorID/ProductIDs
 *  \param[in] ctx talloc context from which to allocate output data
 *  \param[in] luctx libusb context on which to operate
 *  \param[in] dev_ids zero-terminated array of VendorId/ProductId tuples
 *  \returns array of up to 256 libusb_device pointers; NULL in case of error */
libusb_device **osmo_libusb_find_matching_usb_devs(void *ctx, struct libusb_context *luctx,
						   const struct dev_id *dev_ids)
{
	libusb_device **list;
	libusb_device **out = talloc_zero_array(ctx, libusb_device *, 256);
	libusb_device **cur = out;
	unsigned int i;
	int rc;

	if (!out)
		return NULL;

	rc = libusb_get_device_list(luctx, &list);
	if (rc <= 0) {
		perror("No USB devices found");
		talloc_free(out);
		return NULL;
	}

	for (i = 0; list[i] != NULL; i++) {
		struct libusb_device_descriptor dev_desc;
		libusb_device *dev = list[i];

		rc = libusb_get_device_descriptor(dev, &dev_desc);
		if (rc < 0) {
			perror("Couldn't get device descriptor\n");
			libusb_unref_device(dev);
			continue;
		}

		if (match_dev_ids(&dev_desc, dev_ids)) {
			*cur = dev;
			cur++;
			/* overflow check */
			if (cur >= out + 256)
				break;
		} else
			libusb_unref_device(dev);
	}
	if (cur == out) {
		libusb_free_device_list(list, 1);
		talloc_free(out);
		return NULL;
	}

	libusb_free_device_list(list, 0);
	return out;
}

/*! Find a USB device of matching VendorID/ProductID at given path.
 *  \param[in] luctx libusb context on which to operate
 *  \param[in] dev_ids zer-oterminated array of VendorId/ProductId tuples
 *  \param[in] path string representation of USB path
 *  \returns libusb_device if there was exactly one match; NULL otherwise */
libusb_device *osmo_libusb_find_matching_dev_path(struct libusb_context *luctx,
						  const struct dev_id *dev_ids,
						  const char *path)
{
	libusb_device **list;
	libusb_device *match = NULL;
	unsigned int i;
	int rc;

	rc = libusb_get_device_list(luctx, &list);
	if (rc <= 0)
		return NULL;

	for (i = 0; list[i] != NULL; i++) {
		struct libusb_device_descriptor dev_desc;
		libusb_device *dev = list[i];
		char pathbuf[128];

		rc = libusb_get_device_descriptor(dev, &dev_desc);
		if (rc < 0) {
			LOGP(DLUSB, LOGL_ERROR, "couldn't get device descriptor\n");
			continue;
		}

		/* check if device doesn't match */
		if (!match_dev_ids(&dev_desc, dev_ids))
			continue;

		/* check if path doesn't match */
		if (path) {
			osmo_libusb_dev_get_path_buf(pathbuf, sizeof(pathbuf), dev);
			if (strcmp(pathbuf, path))
				continue;
		}

		if (match) {
			/* we already have a match, but now found a second -> FAIL */
			libusb_free_device_list(list, 1);
			LOGP(DLUSB, LOGL_ERROR, "Found more than one matching USB device\n");
			return NULL;
		} else
			match = dev;
	}

	if (!match) {
		/* no match: free the list with automatic unref of all devices */
		libusb_free_device_list(list, 1);
		return NULL;
	}

	/* unref all devices *except* the match we found */
	for (i = 0; list[i] != NULL; i++) {
		libusb_device *dev = list[i];
		if (dev != match)
			libusb_unref_device(dev);
	}
	/* free the list *without* automatic unref of all devices */
	libusb_free_device_list(list, 0);
	return match;
}

/*! Find a USB device of matching VendorID/ProductID and given iSerial string.
 *  \param[in] luctx libusb context on which to operate
 *  \param[in] dev_ids zer-oterminated array of VendorId/ProductId tuples
 *  \param[in] serial string representation of serial number
 *  \returns libusb_device if there was exactly one match; NULL otherwise */
libusb_device *osmo_libusb_find_matching_dev_serial(struct libusb_context *luctx,
						    const struct dev_id *dev_ids,
						    const char *serial)
{
	libusb_device **list;
	libusb_device *match = NULL;
	unsigned int i;
	int rc;

	rc = libusb_get_device_list(luctx, &list);
	if (rc <= 0)
		return NULL;

	for (i = 0; list[i] != NULL; i++) {
		struct libusb_device_descriptor dev_desc;
		libusb_device *dev = list[i];

		rc = libusb_get_device_descriptor(dev, &dev_desc);
		if (rc < 0) {
			LOGP(DLUSB, LOGL_ERROR, "couldn't get device descriptor\n");
			continue;
		}

		/* check if device doesn't match */
		if (!match_dev_ids(&dev_desc, dev_ids))
			continue;

		/* check if serial number string doesn't match */
		if (serial) {
			char strbuf[256];
			libusb_device_handle *devh;
			rc = libusb_open(dev, &devh);
			if (rc < 0) {
				LOGP(DLUSB, LOGL_ERROR, "Cannot open USB Device: %s\n",
					libusb_strerror(rc));
				/* there's no point in continuing here, as we don't know if there
				 * are multiple matches if we cannot read the iSerial string of all
				 * devices with matching vid/pid */
				libusb_free_device_list(list, 1);
				return NULL;
			}
			rc = libusb_get_string_descriptor_ascii(devh, dev_desc.iSerialNumber,
								(uint8_t *) strbuf, sizeof(strbuf));
			if (rc < 0) {
				LOGP(DLUSB, LOGL_ERROR, "Cannot read USB Descriptor: %s\n",
					libusb_strerror(rc));
				libusb_close(devh);
				continue;
			}
			libusb_close(devh);
			if (strcmp(strbuf, serial))
				continue;
		}

		if (match) {
			/* we already have a match, but now found a second -> FAIL */
			libusb_free_device_list(list, 1);
			LOGP(DLUSB, LOGL_ERROR, "Found more than one matching USB device\n");
			return NULL;
		} else
			match = dev;
	}

	if (!match) {
		/* no match: free the list with automatic unref of all devices */
		libusb_free_device_list(list, 1);
		return NULL;
	}

	/* unref all devices *except* the match we found */
	for (i = 0; list[i] != NULL; i++) {
		libusb_device *dev = list[i];
		if (dev != match)
			libusb_unref_device(dev);
	}
	/* free the list *without* automatic unref of all devices */
	libusb_free_device_list(list, 0);
	return match;
}


/*! find a matching interface among all interfaces of the given USB device.
 *  \param[in] dev USB device in which we shall search
 *  \param[in] class USB Interface Class to look for
 *  \param[in] sub_class USB Interface Subclass to look for
 *  \param[in] protocol USB Interface Protocol to look for
 *  \param[out] out User-allocated array for storing matches
 *  \param[in] out_len Length of out array
 *  \returns number of matching interfaces; negative in case of error */
int osmo_libusb_dev_find_matching_interfaces(libusb_device *dev, int class, int sub_class,
					     int protocol, struct usb_interface_match *out,
					     unsigned int out_len)
{
	struct libusb_device_descriptor dev_desc;
	int rc, i, out_idx = 0;
	uint8_t addr;
	char pathbuf[USB_MAX_PATH_LEN];
	char *path;

	rc = libusb_get_device_descriptor(dev, &dev_desc);
	if (rc < 0) {
		perror("Couldn't get device descriptor\n");
		return -EIO;
	}

	addr = libusb_get_device_address(dev);
	path = osmo_libusb_dev_get_path_buf(pathbuf, sizeof(pathbuf), dev);

	/* iterate over all configurations */
	for (i = 0; i < dev_desc.bNumConfigurations; i++) {
		struct libusb_config_descriptor *conf_desc;
		int j;

		rc = libusb_get_config_descriptor(dev, i, &conf_desc);
		if (rc < 0) {
			fprintf(stderr, "Couldn't get config descriptor %u\n", i);
			continue;
		}
		/* iterate over all interfaces */
		for (j = 0; j < conf_desc->bNumInterfaces; j++) {
			const struct libusb_interface *intf = &conf_desc->interface[j];
			int k;
			/* iterate over all alternate settings */
			for (k = 0; k < intf->num_altsetting; k++) {
				const struct libusb_interface_descriptor *if_desc;
				if_desc = &intf->altsetting[k];
				if (class >= 0 && if_desc->bInterfaceClass != class)
					continue;
				if (sub_class >= 0 && if_desc->bInterfaceSubClass != sub_class)
					continue;
				if (protocol >= 0 && if_desc->bInterfaceProtocol != protocol)
					continue;
				/* MATCH! */
				out[out_idx].usb_dev = dev;
				out[out_idx].vendor = dev_desc.idVendor;
				out[out_idx].product = dev_desc.idProduct;
				out[out_idx].addr = addr;
				OSMO_STRLCPY_ARRAY(out[out_idx].path, path);
				out[out_idx].path[sizeof(out[out_idx].path)-1] = '\0';
				out[out_idx].configuration = conf_desc->bConfigurationValue;
				out[out_idx].interface = if_desc->bInterfaceNumber;
				out[out_idx].altsetting = if_desc->bAlternateSetting;
				out[out_idx].class = if_desc->bInterfaceClass;
				out[out_idx].sub_class = if_desc->bInterfaceSubClass;
				out[out_idx].protocol = if_desc->bInterfaceProtocol;
				out[out_idx].string_idx = if_desc->iInterface;
				out_idx++;
				if (out_idx >= out_len)
					return out_idx;
			}
		}
	}
	return out_idx;
}

/*! find matching interfaces among a list devices of specified VendorId/ProductID tuples.
 *  \param[in] luctx libusb context on which to operate
 *  \param[in] dev_ids zero-terminated array of VendorId/ProductId tuples
 *  \param[in] class USB Interface Class to look for
 *  \param[in] sub_class USB Interface Subclass to look for
 *  \param[in] protocol USB Interface Protocol to look for
 *  \param[out] out User-allocated array for storing matches
 *  \param[in] out_len Length of out array
 *  \returns number of matching interfaces; negative in case of error */
int osmo_libusb_find_matching_interfaces(libusb_context *luctx, const struct dev_id *dev_ids,
					 int class, int sub_class, int protocol,
					 struct usb_interface_match *out, unsigned int out_len)
{
	struct usb_interface_match *out_cur = out;
	unsigned int out_len_remain = out_len;
	libusb_device **list;
	libusb_device **dev;

	list = osmo_libusb_find_matching_usb_devs(NULL, luctx, dev_ids);
	if (!list)
		return 0;

	for (dev = list; *dev; dev++) {
		int rc;

#if 0
		struct libusb_device_descriptor dev_desc;
		uint8_t ports[8];
		uint8_t addr;
		rc = libusb_get_device_descriptor(*dev, &dev_desc);
		if (rc < 0) {
			perror("Cannot get device descriptor");
			continue;
		}

		addr = libusb_get_device_address(*dev);

		rc = libusb_get_port_numbers(*dev, ports, sizeof(ports));
		if (rc < 0) {
			perror("Cannot get device path");
			continue;
		}

		printf("Found USB Device %04x:%04x at address %d\n",
			dev_desc.idVendor, dev_desc.idProduct, addr);
#endif

		rc = osmo_libusb_dev_find_matching_interfaces(*dev, class, sub_class,
							      protocol, out_cur, out_len_remain);
		if (rc < 0)
			continue;
		out_cur += rc;
		out_len_remain -= rc;

	}

	/* unref / free list */
	for (dev = list; *dev; dev++)
		libusb_unref_device(*dev);
	talloc_free(list);

	return out_len - out_len_remain;
}

/*! open matching USB device and claim interface
 *  \param[in] ctx talloc context to use for related allocations
 *  \param[in] luctx libusb context on which to operate
 *  \param[in] ifm interface match describing interface to claim
 *  \returns libusb device chandle on success; NULL on error */
libusb_device_handle *osmo_libusb_open_claim_interface(void *ctx, libusb_context *luctx,
							const struct usb_interface_match *ifm)
{
	int rc, config;
	struct dev_id dev_ids[] = { { ifm->vendor, ifm->product }, { 0, 0 } };
	libusb_device **list;
	libusb_device **dev;
	libusb_device_handle *usb_devh = NULL;

	list = osmo_libusb_find_matching_usb_devs(ctx, luctx, dev_ids);
	if (!list) {
		perror("No USB device with matching VID/PID");
		return NULL;
	}

	for (dev = list; *dev; dev++) {
		int addr;
		char pathbuf[USB_MAX_PATH_LEN];
		char *path;

		addr = libusb_get_device_address(*dev);
		path = osmo_libusb_dev_get_path_buf(pathbuf, sizeof(pathbuf), *dev);
		if ((ifm->addr && addr == ifm->addr) ||
		    (strlen(ifm->path) && !strcmp(path, ifm->path))) {
			rc = libusb_open(*dev, &usb_devh);
			if (rc < 0) {
				fprintf(stderr, "Cannot open device: %s\n", libusb_error_name(rc));
				usb_devh = NULL;
				break;
			}
			rc = libusb_get_configuration(usb_devh, &config);
			if (rc < 0) {
				fprintf(stderr, "Cannot get current configuration: %s\n", libusb_error_name(rc));
				libusb_close(usb_devh);
				usb_devh = NULL;
				break;
			}
			if (config != ifm->configuration) {
				rc = libusb_set_configuration(usb_devh, ifm->configuration);
				if (rc < 0) {
					fprintf(stderr, "Cannot set configuration: %s\n", libusb_error_name(rc));
					libusb_close(usb_devh);
					usb_devh = NULL;
					break;
				}
			}
			rc = libusb_claim_interface(usb_devh, ifm->interface);
			if (rc < 0) {
				fprintf(stderr, "Cannot claim interface: %s\n", libusb_error_name(rc));
				libusb_close(usb_devh);
				usb_devh = NULL;
				break;
			}
			rc = libusb_set_interface_alt_setting(usb_devh, ifm->interface, ifm->altsetting);
			if (rc < 0) {
				fprintf(stderr, "Cannot set interface altsetting: %s\n", libusb_error_name(rc));
				libusb_release_interface(usb_devh, ifm->interface);
				libusb_close(usb_devh);
				usb_devh = NULL;
				break;
			}
		}
	}

	/* unref / free list */
	for (dev = list; *dev; dev++)
		libusb_unref_device(*dev);
	talloc_free(list);

	return usb_devh;
}

/*! obtain the endpoint addresses for a given USB interface.
 *  \param[in] devh USB device handle on which to operate
 *  \param[in] if_num USB Interface number on which to operate
 *  \param[out] out user-provided storage for OUT endpoint number
 *  \param[out] in user-provided storage for IN endpoint number
 *  \param[out] irq user-provided storage for IRQ endpoint number
 *  \returns 0 in case of success; negative in case of error */
int osmo_libusb_get_ep_addrs(libusb_device_handle *devh, unsigned int if_num,
			     uint8_t *out, uint8_t *in, uint8_t *irq)
{
	libusb_device *dev = libusb_get_device(devh);
	struct libusb_config_descriptor *cdesc;
	const struct libusb_interface_descriptor *idesc;
	const struct libusb_interface *iface;
	int rc, l;

	rc = libusb_get_active_config_descriptor(dev, &cdesc);
	if (rc < 0)
		return rc;

	iface = &cdesc->interface[if_num];
	/* FIXME: we assume there's no altsetting */
	idesc = &iface->altsetting[0];

	for (l = 0; l < idesc->bNumEndpoints; l++) {
		const struct libusb_endpoint_descriptor *edesc = &idesc->endpoint[l];
		switch (edesc->bmAttributes & 3) {
		case LIBUSB_TRANSFER_TYPE_BULK:
			if (edesc->bEndpointAddress & 0x80) {
				if (in)
					*in = edesc->bEndpointAddress;
			} else {
				if (out)
					*out = edesc->bEndpointAddress;
			}
			break;
		case LIBUSB_TRANSFER_TYPE_INTERRUPT:
			if (irq)
				*irq = edesc->bEndpointAddress;
			break;
		default:
			break;
		}
	}
	return 0;
}
/***********************************************************************
 * initialization
 ***********************************************************************/

int osmo_libusb_init(libusb_context **pluctx)
{
	libusb_context *luctx = NULL;
	int rc;

	rc = libusb_init(pluctx);
	if (rc != 0)
		return rc;

	if (pluctx)
		luctx = *pluctx;

#ifdef LIBUSB_LOG_CB_CONTEXT /* introduced in 1.0.23 */
	libusb_set_log_cb(luctx, &libosmo_usb_log_cb, LIBUSB_LOG_CB_CONTEXT);
#endif

	libusb_set_pollfd_notifiers(luctx, osmo_usb_added_cb, osmo_usb_removed_cb, luctx);

	return 0;
}

void osmo_libusb_exit(libusb_context *luctx)
{
	/* we just assume libusb is cleaning up all the osmo_Fd's we've allocated */
	libusb_exit(luctx);
}
