/*
 * Copyright (c) 2019 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/uart.h>
#include <string.h>
#include <zephyr/random/rand32.h>

#include <zephyr/usb/usb_device.h>
#include <zephyr/usb/class/usb_hid.h>
#include <zephyr/usb/class/usb_cdc.h>

#define LOG_LEVEL LOG_LEVEL_DBG
LOG_MODULE_REGISTER(main);

#define SW0_NODE DT_ALIAS(sw0)

#if DT_NODE_HAS_STATUS(SW0_NODE, okay)
static const struct gpio_dt_spec sw0_gpio = GPIO_DT_SPEC_GET(SW0_NODE, gpios);
#endif

#define SW1_NODE DT_ALIAS(sw1)

#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
static const struct gpio_dt_spec sw1_gpio = GPIO_DT_SPEC_GET(SW1_NODE, gpios);
#endif

#define SW2_NODE DT_ALIAS(sw2)

#if DT_NODE_HAS_STATUS(SW2_NODE, okay)
static const struct gpio_dt_spec sw2_gpio = GPIO_DT_SPEC_GET(SW2_NODE, gpios);
#endif

#define SW3_NODE DT_ALIAS(sw3)

#if DT_NODE_HAS_STATUS(SW3_NODE, okay)
static const struct gpio_dt_spec sw3_gpio = GPIO_DT_SPEC_GET(SW3_NODE, gpios);
#endif

/* Event FIFO */

K_FIFO_DEFINE(evt_fifo);

enum evt_t {
	GPIO_BUTTON_0	= 0x00,
	GPIO_BUTTON_1	= 0x01,
	GPIO_BUTTON_2	= 0x02,
	GPIO_BUTTON_3	= 0x03,
	CDC_UP		= 0x04,
	CDC_DOWN	= 0x05,
	CDC_LEFT	= 0x06,
	CDC_RIGHT	= 0x07,
	CDC_UNKNOWN	= 0x08,
	CDC_STRING	= 0x09,
	HID_MOUSE_CLEAR	= 0x0A,
	HID_KBD_CLEAR	= 0x0B,
	HID_KBD_STRING	= 0x0C,
};

struct app_evt_t {
	sys_snode_t node;
	enum evt_t event_type;
};

#define FIFO_ELEM_MIN_SZ        sizeof(struct app_evt_t)
#define FIFO_ELEM_MAX_SZ        sizeof(struct app_evt_t)
#define FIFO_ELEM_COUNT         255
#define FIFO_ELEM_ALIGN         sizeof(unsigned int)

K_HEAP_DEFINE(event_elem_pool, FIFO_ELEM_MAX_SZ * FIFO_ELEM_COUNT + 256);

static inline void app_evt_free(struct app_evt_t *ev)
{
	k_heap_free(&event_elem_pool, ev);
}

static inline void app_evt_put(struct app_evt_t *ev)
{
	k_fifo_put(&evt_fifo, ev);
}

static inline struct app_evt_t *app_evt_get(void)
{
	return k_fifo_get(&evt_fifo, K_NO_WAIT);
}

static inline void app_evt_flush(void)
{
	struct app_evt_t *ev;

	do {
		ev = app_evt_get();
		if (ev) {
			app_evt_free(ev);
		}
	} while (ev != NULL);
}

static inline struct app_evt_t *app_evt_alloc(void)
{
	struct app_evt_t *ev;

	ev = k_heap_alloc(&event_elem_pool,
			  sizeof(struct app_evt_t),
			  K_NO_WAIT);
	if (ev == NULL) {
		LOG_ERR("APP event allocation failed!");
		app_evt_flush();

		ev = k_heap_alloc(&event_elem_pool,
				  sizeof(struct app_evt_t),
				  K_NO_WAIT);
		if (ev == NULL) {
			LOG_ERR("APP event memory corrupted.");
			__ASSERT_NO_MSG(0);
			return NULL;
		}
		return NULL;
	}

	return ev;
}

/* HID */

static const uint8_t hid_mouse_report_desc[] = HID_MOUSE_REPORT_DESC(2);
static const uint8_t hid_kbd_report_desc[] = HID_KEYBOARD_REPORT_DESC();

static K_SEM_DEFINE(evt_sem, 0, 1);	/* starts off "not available" */
static K_SEM_DEFINE(usb_sem, 1, 1);	/* starts off "available" */
static struct gpio_callback callback[4];

static char data_buf_mouse[64], data_buf_kbd[64];
static char string[64];
static uint8_t chr_ptr_mouse, chr_ptr_kbd, str_pointer;

#define MOUSE_BTN_REPORT_POS	0
#define MOUSE_X_REPORT_POS	1
#define MOUSE_Y_REPORT_POS	2

#define MOUSE_BTN_LEFT		BIT(0)
#define MOUSE_BTN_RIGHT		BIT(1)
#define MOUSE_BTN_MIDDLE	BIT(2)

static const char *welcome	=	"Welcome to ";
static const char *banner0	=	"\r\n"
					"Supported commands:\r\n"
					"up    - moves the mouse up\r\n"
					"down  - moves the mouse down\r\n"
					"right - moves the mouse to right\r\n"
					"left  - moves the mouse to left\r\n";
static const char *banner1	=	"\r\n"
					"Enter a string and terminate "
					"it with ENTER.\r\n"
					"It will be sent via HID "
					"when BUTTON 2 is pressed.\r\n"
					"You can modify it by sending "
					"a new one here.\r\n";
static const char *gpio0	=	"Button 0 pressed\r\n";
static const char *gpio1	=	"Button 1 pressed\r\n";
static const char *gpio2	=	"Button 2 pressed\r\n";
static const char *gpio3	=	"Button 3 pressed\r\n";
static const char *unknown	=	"Command not recognized.\r\n";
static const char *up		=	"Mouse up\r\n";
static const char *down		=	"Mouse down\r\n";
static const char *left		=	"Mouse left\r\n";
static const char *right	=	"Mouse right\r\n";
static const char *evt_fail	=	"Unknown event detected!\r\n";
static const char *set_str	=	"String set to: ";
static const char *endl		=	"\r\n";

static void in_ready_cb(const struct device *dev)
{
	ARG_UNUSED(dev);

	k_sem_give(&usb_sem);
}

static const struct hid_ops ops = {
	.int_in_ready = in_ready_cb,
};

static void clear_mouse_report(void)
{
	struct app_evt_t *new_evt = app_evt_alloc();

	new_evt->event_type = HID_MOUSE_CLEAR;
	app_evt_put(new_evt);
	k_sem_give(&evt_sem);
}

static void clear_kbd_report(void)
{
	struct app_evt_t *new_evt = app_evt_alloc();

	new_evt->event_type = HID_KBD_CLEAR;
	app_evt_put(new_evt);
	k_sem_give(&evt_sem);
}

static int ascii_to_hid(uint8_t ascii)
{
	if (ascii < 32) {
		/* Character not supported */
		return -1;
	} else if (ascii < 48) {
		/* Special characters */
		switch (ascii) {
		case 32:
			return HID_KEY_SPACE;
		case 33:
			return HID_KEY_1;
		case 34:
			return HID_KEY_APOSTROPHE;
		case 35:
			return HID_KEY_3;
		case 36:
			return HID_KEY_4;
		case 37:
			return HID_KEY_5;
		case 38:
			return HID_KEY_7;
		case 39:
			return HID_KEY_APOSTROPHE;
		case 40:
			return HID_KEY_9;
		case 41:
			return HID_KEY_0;
		case 42:
			return HID_KEY_8;
		case 43:
			return HID_KEY_EQUAL;
		case 44:
			return HID_KEY_COMMA;
		case 45:
			return HID_KEY_MINUS;
		case 46:
			return HID_KEY_DOT;
		case 47:
			return HID_KEY_SLASH;
		default:
			return -1;
		}
	} else if (ascii < 58) {
		/* Numbers */
		if (ascii == 48U) {
			return HID_KEY_0;
		} else {
			return ascii - 19;
		}
	} else if (ascii < 65) {
		/* Special characters #2 */
		switch (ascii) {
		case 58:
			return HID_KEY_SEMICOLON;
		case 59:
			return HID_KEY_SEMICOLON;
		case 60:
			return HID_KEY_COMMA;
		case 61:
			return HID_KEY_EQUAL;
		case 62:
			return HID_KEY_DOT;
		case 63:
			return HID_KEY_SLASH;
		case 64:
			return HID_KEY_2;
		default:
			return -1;
		}
	} else if (ascii < 91) {
		/* Uppercase characters */
		return ascii - 61U;
	} else if (ascii < 97) {
		/* Special characters #3 */
		switch (ascii) {
		case 91:
			return HID_KEY_LEFTBRACE;
		case 92:
			return HID_KEY_BACKSLASH;
		case 93:
			return HID_KEY_RIGHTBRACE;
		case 94:
			return HID_KEY_6;
		case 95:
			return HID_KEY_MINUS;
		case 96:
			return HID_KEY_GRAVE;
		default:
			return -1;
		}
	} else if (ascii < 123) {
		/* Lowercase letters */
		return ascii - 93;
	} else if (ascii < 128) {
		/* Special characters #4 */
		switch (ascii) {
		case 123:
			return HID_KEY_LEFTBRACE;
		case 124:
			return HID_KEY_BACKSLASH;
		case 125:
			return HID_KEY_RIGHTBRACE;
		case 126:
			return HID_KEY_GRAVE;
		case 127:
			return HID_KEY_DELETE;
		default:
			return -1;
		}
	}

	return -1;
}

static bool needs_shift(uint8_t ascii)
{
	if ((ascii < 33) || (ascii == 39U)) {
		return false;
	} else if ((ascii >= 33U) && (ascii < 44)) {
		return true;
	} else if ((ascii >= 44U) && (ascii < 58)) {
		return false;
	} else if ((ascii == 59U) || (ascii == 61U)) {
		return false;
	} else if ((ascii >= 58U) && (ascii < 91)) {
		return true;
	} else if ((ascii >= 91U) && (ascii < 94)) {
		return false;
	} else if ((ascii == 94U) || (ascii == 95U)) {
		return true;
	} else if ((ascii > 95) && (ascii < 123)) {
		return false;
	} else if ((ascii > 122) && (ascii < 127)) {
		return true;
	} else {
		return false;
	}
}

/* CDC ACM */

static volatile bool data_transmitted;
static volatile bool data_arrived;

static void flush_buffer_mouse(void)
{
	chr_ptr_mouse = 0U;
	memset(data_buf_mouse, 0, sizeof(data_buf_mouse));
}

static void flush_buffer_kbd(void)
{
	chr_ptr_kbd = 0U;
	memset(data_buf_kbd, 0, sizeof(data_buf_kbd));
}

static void write_data(const struct device *dev, const char *buf, int len)
{
	uart_irq_tx_enable(dev);

	while (len) {
		int written;

		data_transmitted = false;
		written = uart_fifo_fill(dev, (const uint8_t *)buf, len);
		while (data_transmitted == false) {
			k_yield();
		}

		len -= written;
		buf += written;
	}

	uart_irq_tx_disable(dev);
}

static void cdc_mouse_int_handler(const struct device *dev, void *user_data)
{
	ARG_UNUSED(user_data);

	uart_irq_update(dev);

	if (uart_irq_tx_ready(dev)) {
		data_transmitted = true;
	}

	if (!uart_irq_rx_ready(dev)) {
		return;
	}
	uint32_t bytes_read;

	while ((bytes_read = uart_fifo_read(dev,
		(uint8_t *)data_buf_mouse+chr_ptr_mouse,
		sizeof(data_buf_mouse)-chr_ptr_mouse))) {
		chr_ptr_mouse += bytes_read;
		if (data_buf_mouse[chr_ptr_mouse - 1] == '\r') {
			/* ENTER */
			struct app_evt_t *ev = app_evt_alloc();

			data_buf_mouse[chr_ptr_mouse - 1] = '\0';

			if (!strcmp(data_buf_mouse, "up")) {
				ev->event_type = CDC_UP;
			} else if (!strcmp(data_buf_mouse, "down")) {
				ev->event_type = CDC_DOWN;
			} else if (!strcmp(data_buf_mouse, "right")) {
				ev->event_type = CDC_RIGHT;
			} else if (!strcmp(data_buf_mouse, "left")) {
				ev->event_type = CDC_LEFT;
			} else {
				ev->event_type = CDC_UNKNOWN;
			}
			flush_buffer_mouse();
			app_evt_put(ev);
			k_sem_give(&evt_sem);
		}

		if (chr_ptr_mouse >= sizeof(data_buf_mouse)) {
			LOG_WRN("Buffer overflow");
			flush_buffer_mouse();
		}
	}
}

static void cdc_kbd_int_handler(const struct device *dev, void *user_data)
{
	ARG_UNUSED(user_data);

	uart_irq_update(dev);

	if (uart_irq_tx_ready(dev)) {
		data_transmitted = true;
	}

	if (!uart_irq_rx_ready(dev)) {
		return;
	}
	uint32_t bytes_read;

	while ((bytes_read = uart_fifo_read(dev,
		(uint8_t *)data_buf_kbd+chr_ptr_kbd,
		sizeof(data_buf_kbd)-chr_ptr_kbd))) {
		chr_ptr_kbd += bytes_read;
		if (data_buf_kbd[chr_ptr_kbd - 1] == '\r') {
			/* ENTER */
			struct app_evt_t *ev = app_evt_alloc();

			data_buf_kbd[chr_ptr_kbd - 1] = '\0';
			strcpy(string, data_buf_kbd);
			ev->event_type = CDC_STRING;
			flush_buffer_kbd();
			app_evt_put(ev);
			k_sem_give(&evt_sem);
		}
	}
}

/* Devices */

static void btn0(const struct device *gpio, struct gpio_callback *cb,
		 uint32_t pins)
{
	struct app_evt_t *ev = app_evt_alloc();

	ev->event_type = GPIO_BUTTON_0,
	app_evt_put(ev);
	k_sem_give(&evt_sem);
}

#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
static void btn1(const struct device *gpio, struct gpio_callback *cb,
		 uint32_t pins)
{
	struct app_evt_t *ev = app_evt_alloc();

	ev->event_type = GPIO_BUTTON_1,
	app_evt_put(ev);
	k_sem_give(&evt_sem);
}
#endif

#if DT_NODE_HAS_STATUS(SW2_NODE, okay)
static void btn2(const struct device *gpio, struct gpio_callback *cb,
		 uint32_t pins)
{
	struct app_evt_t *ev = app_evt_alloc();

	ev->event_type = GPIO_BUTTON_2,
	app_evt_put(ev);
	k_sem_give(&evt_sem);
}
#endif

#if DT_NODE_HAS_STATUS(SW3_NODE, okay)
static void btn3(const struct device *gpio, struct gpio_callback *cb,
		 uint32_t pins)
{
	struct app_evt_t *ev = app_evt_alloc();

	ev->event_type = GPIO_BUTTON_3,
	app_evt_put(ev);
	k_sem_give(&evt_sem);
}
#endif

int callbacks_configure(const struct gpio_dt_spec *gpio,
			void (*handler)(const struct device *, struct gpio_callback*,
					uint32_t),
			struct gpio_callback *callback)
{
	if (!device_is_ready(gpio->port)) {
		LOG_ERR("%s: device not ready.", gpio->port->name);
		return -ENODEV;
	}

	gpio_pin_configure_dt(gpio, GPIO_INPUT);

	gpio_init_callback(callback, handler, BIT(gpio->pin));
	gpio_add_callback(gpio->port, callback);
	gpio_pin_interrupt_configure_dt(gpio, GPIO_INT_EDGE_TO_ACTIVE);

	return 0;
}

static void status_cb(enum usb_dc_status_code status, const uint8_t *param)
{
	LOG_INF("Status %d", status);
}

#define DEVICE_AND_COMMA(node_id) DEVICE_DT_GET(node_id),

void main(void)
{
	const struct device *cdc_dev[] = {
		DT_FOREACH_STATUS_OKAY(zephyr_cdc_acm_uart, DEVICE_AND_COMMA)
	};
	BUILD_ASSERT(ARRAY_SIZE(cdc_dev) >= 2, "Not enough CDC ACM instances");
	const struct device *hid0_dev, *hid1_dev;
	struct app_evt_t *ev;
	uint32_t dtr = 0U;
	int ret;

	/* Configure devices */

	hid0_dev = device_get_binding("HID_0");
	if (hid0_dev == NULL) {
		LOG_ERR("Cannot get USB HID 0 Device");
		return;
	}

	hid1_dev = device_get_binding("HID_1");
	if (hid1_dev == NULL) {
		LOG_ERR("Cannot get USB HID 1 Device");
		return;
	}

	for (int idx = 0; idx < ARRAY_SIZE(cdc_dev); idx++) {
		if (!device_is_ready(cdc_dev[idx])) {
			LOG_ERR("CDC ACM device %s is not ready",
				cdc_dev[idx]->name);
			return;
		}
	}

	if (callbacks_configure(&sw0_gpio, &btn0, &callback[0])) {
		LOG_ERR("Failed configuring button 0 callback.");
		return;
	}

#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
	if (callbacks_configure(&sw1_gpio, &btn1, &callback[1])) {
		LOG_ERR("Failed configuring button 1 callback.");
		return;
	}
#endif

#if DT_NODE_HAS_STATUS(SW2_NODE, okay)
	if (callbacks_configure(&sw2_gpio, &btn2, &callback[2])) {
		LOG_ERR("Failed configuring button 2 callback.");
		return;
	}
#endif

#if DT_NODE_HAS_STATUS(SW3_NODE, okay)
	if (callbacks_configure(&sw3_gpio, &btn3, &callback[3])) {
		LOG_ERR("Failed configuring button 3 callback.");
		return;
	}
#endif

	/* Initialize HID */

	usb_hid_register_device(hid0_dev, hid_mouse_report_desc,
				sizeof(hid_mouse_report_desc), &ops);

	usb_hid_register_device(hid1_dev, hid_kbd_report_desc,
				sizeof(hid_kbd_report_desc), &ops);

	usb_hid_init(hid0_dev);
	usb_hid_init(hid1_dev);

	ret = usb_enable(status_cb);
	if (ret != 0) {
		LOG_ERR("Failed to enable USB");
		return;
	}

	/* Initialize CDC ACM */
	for (int idx = 0; idx < ARRAY_SIZE(cdc_dev); idx++) {
		LOG_INF("Wait for DTR on %s", cdc_dev[idx]->name);
		while (1) {
			uart_line_ctrl_get(cdc_dev[idx],
					   UART_LINE_CTRL_DTR,
					   &dtr);
			if (dtr) {
				break;
			} else {
				/* Give CPU resources to low priority threads. */
				k_sleep(K_MSEC(100));
			}
		}

		LOG_INF("DTR on device %s", cdc_dev[idx]->name);
	}

	/* Wait 1 sec for the host to do all settings */
	k_busy_wait(USEC_PER_SEC);

	uart_irq_callback_set(cdc_dev[0], cdc_mouse_int_handler);
	uart_irq_callback_set(cdc_dev[1], cdc_kbd_int_handler);

	write_data(cdc_dev[0], welcome, strlen(welcome));
	write_data(cdc_dev[0], cdc_dev[0]->name, strlen(cdc_dev[0]->name));
	write_data(cdc_dev[0], banner0, strlen(banner0));
	write_data(cdc_dev[1], welcome, strlen(welcome));
	write_data(cdc_dev[1], cdc_dev[1]->name, strlen(cdc_dev[1]->name));
	write_data(cdc_dev[1], banner1, strlen(banner1));

	uart_irq_rx_enable(cdc_dev[0]);
	uart_irq_rx_enable(cdc_dev[1]);

	while (true) {
		k_sem_take(&evt_sem, K_FOREVER);

		while ((ev = app_evt_get()) != NULL) {
			switch (ev->event_type) {
			case GPIO_BUTTON_0:
			{
				/* Move the mouse in random direction */
				uint8_t rep[] = {0x00, sys_rand32_get(),
					      sys_rand32_get(), 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[0], gpio0, strlen(gpio0));
				clear_mouse_report();
				break;
			}
			case GPIO_BUTTON_1:
			{
				/* Press left mouse button */
				uint8_t rep[] = {0x00, 0x00, 0x00, 0x00};

				rep[MOUSE_BTN_REPORT_POS] |= MOUSE_BTN_LEFT;
				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[0], gpio1, strlen(gpio1));
				clear_mouse_report();
				break;
			}
			case GPIO_BUTTON_2:
			{
				/* Send string on HID keyboard */
				write_data(cdc_dev[1], gpio2, strlen(gpio2));
				if (strlen(string) > 0) {
					struct app_evt_t *ev = app_evt_alloc();

					ev->event_type = HID_KBD_STRING,
					app_evt_put(ev);
					str_pointer = 0U;
					k_sem_give(&evt_sem);
				}
				break;
			}
			case GPIO_BUTTON_3:
			{
				/* Toggle CAPS LOCK */
				uint8_t rep[] = {0x00, 0x00, 0x00, 0x00,
					      0x00, 0x00, 0x00,
					      HID_KEY_CAPSLOCK};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid1_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[1], gpio3, strlen(gpio3));
				clear_kbd_report();
				break;
			}
			case CDC_UP:
			{
				/* Mouse up */
				uint8_t rep[] = {0x00, 0x00, 0xE0, 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[0], up, strlen(up));
				clear_mouse_report();
				break;
			}
			case CDC_DOWN:
			{
				/* Mouse down */
				uint8_t rep[] = {0x00, 0x00, 0x20, 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[0], down, strlen(down));
				clear_mouse_report();
				break;
			}
			case CDC_RIGHT:
			{
				/* Mouse right */
				uint8_t rep[] = {0x00, 0x20, 0x00, 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[0], right, strlen(right));
				clear_mouse_report();
				break;
			}
			case CDC_LEFT:
			{
				/* Mouse left */
				uint8_t rep[] = {0x00, 0xE0, 0x00, 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				write_data(cdc_dev[0], left, strlen(left));
				clear_mouse_report();
				break;
			}
			case CDC_UNKNOWN:
			{
				write_data(cdc_dev[0], unknown, strlen(unknown));
				write_data(cdc_dev[1], unknown, strlen(unknown));
				break;
			}
			case CDC_STRING:
			{
				write_data(cdc_dev[0], set_str, strlen(set_str));
				write_data(cdc_dev[0], string, strlen(string));
				write_data(cdc_dev[0], endl, strlen(endl));

				write_data(cdc_dev[1], set_str, strlen(set_str));
				write_data(cdc_dev[1], string, strlen(string));
				write_data(cdc_dev[1], endl, strlen(endl));
				break;
			}
			case HID_MOUSE_CLEAR:
			{
				/* Clear mouse report */
				uint8_t rep[] = {0x00, 0x00, 0x00, 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid0_dev, rep,
						 sizeof(rep), NULL);
				break;
			}
			case HID_KBD_CLEAR:
			{
				/* Clear kbd report */
				uint8_t rep[] = {0x00, 0x00, 0x00, 0x00,
					      0x00, 0x00, 0x00, 0x00};

				k_sem_take(&usb_sem, K_FOREVER);
				hid_int_ep_write(hid1_dev, rep,
						 sizeof(rep), NULL);
				break;
			}
			case HID_KBD_STRING:
			{
				int ch = ascii_to_hid(string[str_pointer]);

				if (ch == -1) {
					LOG_WRN("Unsupported character: %d",
						string[str_pointer]);
				} else {
					uint8_t rep[] = {0x00, 0x00, 0x00, 0x00,
						      0x00, 0x00, 0x00, 0x00};
					if (needs_shift(string[str_pointer])) {
						rep[0] |=
						HID_KBD_MODIFIER_RIGHT_SHIFT;
					}
					rep[7] = ch;

					k_sem_take(&usb_sem, K_FOREVER);
					hid_int_ep_write(hid1_dev, rep,
							sizeof(rep), NULL);
				}

				str_pointer++;

				if (strlen(string) > str_pointer) {
					struct app_evt_t *ev = app_evt_alloc();

					ev->event_type = HID_KBD_STRING,
					app_evt_put(ev);
					k_sem_give(&evt_sem);
				} else if (strlen(string) == str_pointer) {
					clear_kbd_report();
				}

				break;
			}
			default:
			{
				LOG_ERR("Unknown event to execute");
				write_data(cdc_dev[0], evt_fail,
					   strlen(evt_fail));
				write_data(cdc_dev[1], evt_fail,
					   strlen(evt_fail));
				break;
			}
			break;
			}
			app_evt_free(ev);
		}
	}
}
