/* usb_descriptor.c - USB common device descriptor definition */

/*
 * Copyright (c) 2017 PHYTEC Messtechnik GmbH
 * Copyright (c) 2017, 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>
#include <usb/usbstruct.h>
#include <usb/usb_device.h>
#include <usb/usb_common.h>
#include "usb_descriptor.h"
#include <drivers/hwinfo.h>

#define LOG_LEVEL CONFIG_USB_DEVICE_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(usb_descriptor);

/*
 * The last index of the initializer_string without null character is:
 *   ascii_idx_max = bLength / 2 - 2
 * Use this macro to determine the last index of ASCII7 string.
 */
#define USB_BSTRING_ASCII_IDX_MAX(n)	(n / 2 - 2)

/*
 * The last index of the bString is:
 *   utf16le_idx_max = sizeof(initializer_string) * 2 - 2 - 1
 *   utf16le_idx_max = bLength - 2 - 1
 * Use this macro to determine the last index of UTF16LE string.
 */
#define USB_BSTRING_UTF16LE_IDX_MAX(n)	(n - 3)

/* Linker-defined symbols bound the USB descriptor structs */
extern struct usb_desc_header __usb_descriptor_start[];
extern struct usb_desc_header __usb_descriptor_end[];
extern struct usb_cfg_data __usb_data_start[];
extern struct usb_cfg_data __usb_data_end[];

/* Structure representing the global USB description */
struct common_descriptor {
	struct usb_device_descriptor device_descriptor;
	struct usb_cfg_descriptor cfg_descr;
} __packed;

#define USB_DESC_MANUFACTURER_IDX			1
#define USB_DESC_PRODUCT_IDX				2
#define USB_DESC_SERIAL_NUMBER_IDX			3

/*
 * Device and configuration descriptor placed in the device section,
 * no additional descriptor may be placed there.
 */
USBD_DEVICE_DESCR_DEFINE(primary) struct common_descriptor common_desc = {
	/* Device descriptor */
	.device_descriptor = {
		.bLength = sizeof(struct usb_device_descriptor),
		.bDescriptorType = USB_DEVICE_DESC,
#ifdef CONFIG_USB_DEVICE_BOS
		.bcdUSB = sys_cpu_to_le16(USB_2_1),
#else
		.bcdUSB = sys_cpu_to_le16(USB_2_0),
#endif
#ifdef CONFIG_USB_COMPOSITE_DEVICE
		.bDeviceClass = MISC_CLASS,
		.bDeviceSubClass = 0x02,
		.bDeviceProtocol = 0x01,
#else
		.bDeviceClass = 0,
		.bDeviceSubClass = 0,
		.bDeviceProtocol = 0,
#endif
		.bMaxPacketSize0 = USB_MAX_CTRL_MPS,
		.idVendor = sys_cpu_to_le16((u16_t)CONFIG_USB_DEVICE_VID),
		.idProduct = sys_cpu_to_le16((u16_t)CONFIG_USB_DEVICE_PID),
		.bcdDevice = sys_cpu_to_le16(BCDDEVICE_RELNUM),
		.iManufacturer = USB_DESC_MANUFACTURER_IDX,
		.iProduct = USB_DESC_PRODUCT_IDX,
		.iSerialNumber = USB_DESC_SERIAL_NUMBER_IDX,
		.bNumConfigurations = 1,
	},
	/* Configuration descriptor */
	.cfg_descr = {
		.bLength = sizeof(struct usb_cfg_descriptor),
		.bDescriptorType = USB_CONFIGURATION_DESC,
		/*wTotalLength will be fixed in usb_fix_descriptor() */
		.wTotalLength = 0,
		.bNumInterfaces = 0,
		.bConfigurationValue = 1,
		.iConfiguration = 0,
		.bmAttributes = USB_CONFIGURATION_ATTRIBUTES,
		.bMaxPower = CONFIG_USB_MAX_POWER,
	},
};

struct usb_string_desription {
	struct usb_string_descriptor lang_descr;
	struct usb_mfr_descriptor {
		u8_t bLength;
		u8_t bDescriptorType;
		u8_t bString[USB_BSTRING_LENGTH(
				CONFIG_USB_DEVICE_MANUFACTURER)];
	} __packed utf16le_mfr;

	struct usb_product_descriptor {
		u8_t bLength;
		u8_t bDescriptorType;
		u8_t bString[USB_BSTRING_LENGTH(CONFIG_USB_DEVICE_PRODUCT)];
	} __packed utf16le_product;

	struct usb_sn_descriptor {
		u8_t bLength;
		u8_t bDescriptorType;
		u8_t bString[USB_BSTRING_LENGTH(CONFIG_USB_DEVICE_SN)];
	} __packed utf16le_sn;
} __packed;

/*
 * Language, Manufacturer, Product and Serial string descriptors,
 * placed in the string section.
 * FIXME: These should be sorted additionally.
 */
USBD_STRING_DESCR_DEFINE(primary) struct usb_string_desription string_descr = {
	.lang_descr = {
		.bLength = sizeof(struct usb_string_descriptor),
		.bDescriptorType = USB_STRING_DESC,
		.bString = sys_cpu_to_le16(0x0409),
	},
	/* Manufacturer String Descriptor */
	.utf16le_mfr = {
		.bLength = USB_STRING_DESCRIPTOR_LENGTH(
				CONFIG_USB_DEVICE_MANUFACTURER),
		.bDescriptorType = USB_STRING_DESC,
		.bString = CONFIG_USB_DEVICE_MANUFACTURER,
	},
	/* Product String Descriptor */
	.utf16le_product = {
		.bLength = USB_STRING_DESCRIPTOR_LENGTH(
				CONFIG_USB_DEVICE_PRODUCT),
		.bDescriptorType = USB_STRING_DESC,
		.bString = CONFIG_USB_DEVICE_PRODUCT,
	},
	/* Serial Number String Descriptor */
	.utf16le_sn = {
		.bLength = USB_STRING_DESCRIPTOR_LENGTH(CONFIG_USB_DEVICE_SN),
		.bDescriptorType = USB_STRING_DESC,
		.bString = CONFIG_USB_DEVICE_SN,
	},
};

/* This element marks the end of the entire descriptor. */
USBD_TERM_DESCR_DEFINE(primary) struct usb_desc_header term_descr = {
	.bLength = 0,
	.bDescriptorType = 0,
};

/*
 * This function fixes bString by transforming the ASCII-7 string
 * into a UTF16-LE during runtime.
 */
static void ascii7_to_utf16le(void *descriptor)
{
	struct usb_string_descriptor *str_descr = descriptor;
	int idx_max = USB_BSTRING_UTF16LE_IDX_MAX(str_descr->bLength);
	int ascii_idx_max = USB_BSTRING_ASCII_IDX_MAX(str_descr->bLength);
	u8_t *buf = (u8_t *)&str_descr->bString;

	LOG_DBG("idx_max %d, ascii_idx_max %d, buf %p",
		idx_max, ascii_idx_max, buf);

	for (int i = idx_max; i >= 0; i -= 2) {
		LOG_DBG("char %c : %x, idx %d -> %d",
			buf[ascii_idx_max],
			buf[ascii_idx_max],
			ascii_idx_max, i);
		__ASSERT(buf[ascii_idx_max] > 0x1F && buf[ascii_idx_max] < 0x7F,
			 "Only printable ascii-7 characters are allowed in USB "
			 "string descriptors");
		buf[i] = 0U;
		buf[i - 1] = buf[ascii_idx_max--];
	}
}

/*
 * Look for the bString that has the address equal to the ptr and
 * return its index. Use it to determine the index of the bString and
 * assign it to the interfaces iInterface variable.
 */
int usb_get_str_descriptor_idx(void *ptr)
{
	struct usb_desc_header *head = __usb_descriptor_start;
	struct usb_string_descriptor *str = ptr;
	int str_descr_idx = 0;

	while (head->bLength != 0U) {
		switch (head->bDescriptorType) {
		case USB_STRING_DESC:
			if (head == (struct usb_desc_header *)str) {
				return str_descr_idx;
			}

			str_descr_idx += 1;
			break;
		default:
			break;
		}

		/* move to next descriptor */
		head = (struct usb_desc_header *)((u8_t *)head + head->bLength);
	}

	return 0;
}

/*
 * Validate endpoint address and Update the endpoint descriptors at runtime,
 * the result depends on the capabilities of the driver and the number and
 * type of endpoints.
 * The default endpoint address is stored in endpoint descriptor and
 * usb_ep_cfg_data, so both variables bEndpointAddress and ep_addr need
 * to be updated.
 */
static int usb_validate_ep_cfg_data(struct usb_ep_descriptor * const ep_descr,
				    struct usb_cfg_data * const cfg_data,
				    u32_t *requested_ep)
{
	for (int i = 0; i < cfg_data->num_endpoints; i++) {
		struct usb_ep_cfg_data *ep_data = cfg_data->endpoint;

		/*
		 * Trying to find the right entry in the usb_ep_cfg_data.
		 */
		if (ep_descr->bEndpointAddress != ep_data[i].ep_addr) {
			continue;
		}

		for (u8_t idx = 1; idx < 16; idx++) {
			struct usb_dc_ep_cfg_data ep_cfg;

			ep_cfg.ep_type = (ep_descr->bmAttributes &
					  USB_EP_TRANSFER_TYPE_MASK);
			ep_cfg.ep_mps = ep_descr->wMaxPacketSize;
			ep_cfg.ep_addr = ep_descr->bEndpointAddress;
			if (ep_cfg.ep_addr & USB_EP_DIR_IN) {
				if ((*requested_ep & (1 << (idx + 16)))) {
					continue;
				}

				ep_cfg.ep_addr = (USB_EP_DIR_IN | idx);
			} else {
				if ((*requested_ep & (1 << (idx)))) {
					continue;
				}

				ep_cfg.ep_addr = idx;
			}
			if (!usb_dc_ep_check_cap(&ep_cfg)) {
				LOG_DBG("Fixing EP address %x -> %x",
					ep_descr->bEndpointAddress,
					ep_cfg.ep_addr);
				ep_descr->bEndpointAddress = ep_cfg.ep_addr;
				ep_data[i].ep_addr = ep_cfg.ep_addr;
				if (ep_cfg.ep_addr & USB_EP_DIR_IN) {
					*requested_ep |= (1 << (idx + 16));
				} else {
					*requested_ep |= (1 << idx);
				}
				LOG_DBG("endpoint 0x%x", ep_data[i].ep_addr);
				return 0;
			}
		}
	}
	return -1;
}

/*
 * The interface descriptor of a USB function must be assigned to the
 * usb_cfg_data so that usb_ep_cfg_data and matching endpoint descriptor
 * can be found.
 */
static struct usb_cfg_data *usb_get_cfg_data(struct usb_if_descriptor *iface)
{
	size_t length = (__usb_data_end - __usb_data_start);

	for (size_t i = 0; i < length; i++) {
		if (__usb_data_start[i].interface_descriptor == iface) {
			return &__usb_data_start[i];
		}
	}

	return NULL;
}

/*
 * Default USB Serial Number string descriptor will be derived from
 * Hardware Information Driver (HWINFO). User can implement own variant
 * of this function. Please note that the length of the new Serial Number
 * descriptor may not exceed the length of the CONFIG_USB_DEVICE_SN.
 */
__weak u8_t *usb_update_sn_string_descriptor(void)
{
	u8_t hwid[sizeof(CONFIG_USB_DEVICE_SN) / 2];
	static u8_t sn[sizeof(CONFIG_USB_DEVICE_SN) + 1];
	const char hex[] = "0123456789ABCDEF";

	memset(hwid, 0, sizeof(hwid));
	memset(sn, 0, sizeof(sn));

	if (hwinfo_get_device_id(hwid, sizeof(hwid)) > 0) {
		LOG_HEXDUMP_DBG(hwid, sizeof(hwid), "Serial Number");
		for (int i = 0; i < sizeof(hwid); i++) {
			sn[i * 2] = hex[hwid[i] >> 4];
			sn[i * 2 + 1] = hex[hwid[i] & 0xF];
		}
	}

	return sn;
}

static void usb_fix_ascii_sn_string_descriptor(struct usb_sn_descriptor *sn)
{
	u8_t *runtime_sn =  usb_update_sn_string_descriptor();
	int runtime_sn_len, default_sn_len;

	if (!runtime_sn) {
		return;
	}

	runtime_sn_len = strlen(runtime_sn);
	if (!runtime_sn_len) {
		return;
	}

	default_sn_len = strlen(CONFIG_USB_DEVICE_SN);

	if (runtime_sn_len != default_sn_len) {
		LOG_ERR("the new SN descriptor doesn't have the same "
			"length as CONFIG_USB_DEVICE_SN");
		return;
	}

	memcpy(sn->bString, runtime_sn, runtime_sn_len);
}

/*
 * The entire descriptor, placed in the .usb.descriptor section,
 * needs to be fixed before use. Currently, only the length of the
 * entire device configuration (with all interfaces and endpoints)
 * and the string descriptors will be corrected.
 *
 * Restrictions:
 * - just one device configuration (there is only one)
 * - string descriptor must be present
 */
static int usb_fix_descriptor(struct usb_desc_header *head)
{
	struct usb_cfg_descriptor *cfg_descr = NULL;
	struct usb_if_descriptor *if_descr = NULL;
	struct usb_cfg_data *cfg_data = NULL;
	struct usb_ep_descriptor *ep_descr = NULL;
	u8_t numof_ifaces = 0U;
	u8_t str_descr_idx = 0U;
	u32_t requested_ep = BIT(16) | BIT(0);

	while (head->bLength != 0U) {
		switch (head->bDescriptorType) {
		case USB_CONFIGURATION_DESC:
			cfg_descr = (struct usb_cfg_descriptor *)head;
			LOG_DBG("Configuration descriptor %p", head);
			break;
		case USB_ASSOCIATION_DESC:
			LOG_DBG("Association descriptor %p", head);
			break;
		case USB_INTERFACE_DESC:
			if_descr = (struct usb_if_descriptor *)head;
			LOG_DBG("Interface descriptor %p", head);
			if (if_descr->bAlternateSetting) {
				LOG_DBG("Skip alternate interface");
				break;
			}

			if (if_descr->bInterfaceNumber == 0U) {
				cfg_data = usb_get_cfg_data(if_descr);
				if (!cfg_data) {
					LOG_ERR("There is no usb_cfg_data "
						"for %p", head);
					return -1;
				}

				if (cfg_data->interface_config) {
					cfg_data->interface_config(head,
							numof_ifaces);
				}
			}

			numof_ifaces++;
			break;
		case USB_ENDPOINT_DESC:
			if (!cfg_data) {
				LOG_ERR("Uninitialized usb_cfg_data pointer, "
					"corrupted device descriptor?");
				return -1;
			}

			LOG_DBG("Endpoint descriptor %p", head);
			ep_descr = (struct usb_ep_descriptor *)head;
			if (usb_validate_ep_cfg_data(ep_descr,
						     cfg_data,
						     &requested_ep)) {
				LOG_ERR("Failed to validate endpoints");
				return -1;
			}

			break;
		case 0:
		case USB_STRING_DESC:
			/*
			 * Copy runtime SN string descriptor first, if has
			 */
			if (str_descr_idx == USB_DESC_SERIAL_NUMBER_IDX) {
				struct usb_sn_descriptor *sn =
					(struct usb_sn_descriptor *)head;
				usb_fix_ascii_sn_string_descriptor(sn);
			}
			/*
			 * Skip language descriptor but correct
			 * wTotalLength and bNumInterfaces once.
			 */
			if (str_descr_idx) {
				ascii7_to_utf16le(head);
			} else {
				if (!cfg_descr) {
					LOG_ERR("Incomplete device descriptor");
					return -1;
				}

				LOG_DBG("Now the wTotalLength is %zd",
					(u8_t *)head - (u8_t *)cfg_descr);
				sys_put_le16((u8_t *)head - (u8_t *)cfg_descr,
					     (u8_t *)&cfg_descr->wTotalLength);
				cfg_descr->bNumInterfaces = numof_ifaces;
			}

			str_descr_idx += 1U;

			break;
		default:
			break;
		}

		/* Move to next descriptor */
		head = (struct usb_desc_header *)((u8_t *)head + head->bLength);
	}

	if ((head + 1) != __usb_descriptor_end) {
		LOG_DBG("try to fix next descriptor at %p", head + 1);
		return usb_fix_descriptor(head + 1);
	}

	return 0;
}


u8_t *usb_get_device_descriptor(void)
{
	LOG_DBG("__usb_descriptor_start %p", __usb_descriptor_start);
	LOG_DBG("__usb_descriptor_end %p", __usb_descriptor_end);

	if (usb_fix_descriptor(__usb_descriptor_start)) {
		LOG_ERR("Failed to fixup USB descriptor");
		return NULL;
	}

	return (u8_t *) __usb_descriptor_start;
}

struct usb_dev_data *usb_get_dev_data_by_cfg(sys_slist_t *list,
					     struct usb_cfg_data *cfg)
{
	struct usb_dev_data *dev_data;

	SYS_SLIST_FOR_EACH_CONTAINER(list, dev_data, node) {
		struct device *dev = dev_data->dev;
		const struct usb_cfg_data *cfg_cur = dev->config_info;

		if (cfg_cur == cfg) {
			return dev_data;
		}
	}

	LOG_DBG("Device data not found for cfg %p", cfg);

	return NULL;
}

struct usb_dev_data *usb_get_dev_data_by_iface(sys_slist_t *list,
					       u8_t iface_num)
{
	struct usb_dev_data *dev_data;

	SYS_SLIST_FOR_EACH_CONTAINER(list, dev_data, node) {
		struct device *dev = dev_data->dev;
		const struct usb_cfg_data *cfg = dev->config_info;
		const struct usb_if_descriptor *if_desc =
						cfg->interface_descriptor;

		if (if_desc->bInterfaceNumber == iface_num) {
			return dev_data;
		}
	}

	LOG_DBG("Device data not found for iface number %u", iface_num);

	return NULL;
}

struct usb_dev_data *usb_get_dev_data_by_ep(sys_slist_t *list, u8_t ep)
{
	struct usb_dev_data *dev_data;

	SYS_SLIST_FOR_EACH_CONTAINER(list, dev_data, node) {
		struct device *dev = dev_data->dev;
		const struct usb_cfg_data *cfg = dev->config_info;
		const struct usb_ep_cfg_data *ep_data = cfg->endpoint;

		for (u8_t i = 0; i < cfg->num_endpoints; i++) {
			if (ep_data[i].ep_addr == ep) {
				return dev_data;
			}
		}
	}

	LOG_DBG("Device data not found for ep %u", ep);

	return NULL;
}
