/* 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));
			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);
}
