/*
 * Copyright (c) 2022 Vestas Wind Systems A/S
 * Copyright (c) 2019 Alexander Wachter
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <stdio.h>

#include <zephyr/device.h>
#include <zephyr/drivers/can.h>
#include <zephyr/logging/log.h>
#include <zephyr/shell/shell.h>

LOG_MODULE_REGISTER(can_shell, CONFIG_CAN_LOG_LEVEL);

struct can_shell_tx_event {
	unsigned int frame_no;
	int error;
};

struct can_shell_mode_mapping {
	const char *name;
	can_mode_t mode;
};

#define CAN_SHELL_MODE_MAPPING(_name, _mode) { .name = _name, .mode = _mode }

static const struct can_shell_mode_mapping can_shell_mode_map[] = {
	/* Array sorted alphabetically based on name */
	CAN_SHELL_MODE_MAPPING("fd",              CAN_MODE_FD),
	CAN_SHELL_MODE_MAPPING("listen-only",     CAN_MODE_LISTENONLY),
	CAN_SHELL_MODE_MAPPING("loopback",        CAN_MODE_LOOPBACK),
	CAN_SHELL_MODE_MAPPING("normal",          CAN_MODE_NORMAL),
	CAN_SHELL_MODE_MAPPING("one-shot",        CAN_MODE_ONE_SHOT),
	CAN_SHELL_MODE_MAPPING("triple-sampling", CAN_MODE_3_SAMPLES),
};

K_MSGQ_DEFINE(can_shell_tx_msgq, sizeof(struct can_shell_tx_event),
	      CONFIG_CAN_SHELL_TX_QUEUE_SIZE, 4);
const struct shell *can_shell_tx_msgq_sh;
static struct k_work_poll can_shell_tx_msgq_work;
static struct k_poll_event can_shell_tx_msgq_events[] = {
	K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
					K_POLL_MODE_NOTIFY_ONLY,
					&can_shell_tx_msgq, 0)
};

CAN_MSGQ_DEFINE(can_shell_rx_msgq, CONFIG_CAN_SHELL_RX_QUEUE_SIZE);
const struct shell *can_shell_rx_msgq_sh;
static struct k_work_poll can_shell_rx_msgq_work;
static struct k_poll_event can_shell_rx_msgq_events[] = {
	K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
					K_POLL_MODE_NOTIFY_ONLY,
					&can_shell_rx_msgq, 0)
};

/* Forward declarations */
static void can_shell_tx_msgq_triggered_work_handler(struct k_work *work);
static void can_shell_rx_msgq_triggered_work_handler(struct k_work *work);

static void can_shell_print_frame(const struct shell *sh, const struct can_frame *frame)
{
	uint8_t nbytes = can_dlc_to_bytes(frame->dlc);
	int i;

#ifdef CONFIG_CAN_RX_TIMESTAMP
	/* Timestamp */
	shell_fprintf(sh, SHELL_NORMAL, "(%05d)  ", frame->timestamp);
#endif /* CONFIG_CAN_RX_TIMESTAMP */

#ifdef CONFIG_CAN_FD_MODE
	/* Flags */
	shell_fprintf(sh, SHELL_NORMAL, "%c  ", (frame->flags & CAN_FRAME_BRS) == 0 ? '-' : 'B');
#endif /* CONFIG_CAN_FD_MODE */

	/* CAN ID */
	shell_fprintf(sh, SHELL_NORMAL, "%*s%0*x  ",
		(frame->flags & CAN_FRAME_IDE) != 0 ? 0 : 5, "",
		(frame->flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
		(frame->flags & CAN_FRAME_IDE) != 0 ?
		frame->id & CAN_EXT_ID_MASK : frame->id & CAN_STD_ID_MASK);

	/* DLC as number of bytes */
	shell_fprintf(sh, SHELL_NORMAL, "%s[%0*d]  ",
		(frame->flags & CAN_FRAME_FDF) != 0 ? "" : " ",
		(frame->flags & CAN_FRAME_FDF) != 0 ? 2 : 1,
		nbytes);

	/* Data payload */
	if ((frame->flags & CAN_FRAME_RTR) != 0) {
		shell_fprintf(sh, SHELL_NORMAL, "remote transmission request");
	} else {
		for (i = 0; i < nbytes; i++) {
			shell_fprintf(sh, SHELL_NORMAL, "%02x ", frame->data[i]);
		}
	}

	shell_fprintf(sh, SHELL_NORMAL, "\n");
}

static int can_shell_tx_msgq_poll_submit(const struct shell *sh)
{
	int err;

	if (can_shell_tx_msgq_sh == NULL) {
		can_shell_tx_msgq_sh = sh;
		k_work_poll_init(&can_shell_tx_msgq_work, can_shell_tx_msgq_triggered_work_handler);
	}

	err = k_work_poll_submit(&can_shell_tx_msgq_work, can_shell_tx_msgq_events,
				 ARRAY_SIZE(can_shell_tx_msgq_events), K_FOREVER);
	if (err != 0) {
		shell_error(can_shell_tx_msgq_sh, "failed to submit tx msgq polling (err %d)",
			    err);
	}

	return err;
}

static void can_shell_tx_msgq_triggered_work_handler(struct k_work *work)
{
	struct can_shell_tx_event event;

	while (k_msgq_get(&can_shell_tx_msgq, &event, K_NO_WAIT) == 0) {
		if (event.error == 0) {
			shell_print(can_shell_tx_msgq_sh, "CAN frame #%u successfully sent",
				    event.frame_no);
		} else {
			shell_error(can_shell_tx_msgq_sh, "failed to send CAN frame #%u (err %d)",
				    event.frame_no, event.error);
		}
	}

	(void)can_shell_tx_msgq_poll_submit(can_shell_tx_msgq_sh);
}

static void can_shell_tx_callback(const struct device *dev, int error, void *user_data)
{
	struct can_shell_tx_event event;
	int err;

	ARG_UNUSED(dev);

	event.frame_no = POINTER_TO_UINT(user_data);
	event.error = error;

	err = k_msgq_put(&can_shell_tx_msgq, &event, K_NO_WAIT);
	if (err != 0) {
		LOG_ERR("CAN shell tx event queue full");
	}
}

static int can_shell_rx_msgq_poll_submit(const struct shell *sh)
{
	int err;

	if (can_shell_rx_msgq_sh == NULL) {
		can_shell_rx_msgq_sh = sh;
		k_work_poll_init(&can_shell_rx_msgq_work, can_shell_rx_msgq_triggered_work_handler);
	}

	err = k_work_poll_submit(&can_shell_rx_msgq_work, can_shell_rx_msgq_events,
				 ARRAY_SIZE(can_shell_rx_msgq_events), K_FOREVER);
	if (err != 0) {
		shell_error(can_shell_rx_msgq_sh, "failed to submit rx msgq polling (err %d)",
			    err);
	}

	return err;
}

static void can_shell_rx_msgq_triggered_work_handler(struct k_work *work)
{
	struct can_frame frame;

	while (k_msgq_get(&can_shell_rx_msgq, &frame, K_NO_WAIT) == 0) {
		can_shell_print_frame(can_shell_rx_msgq_sh, &frame);
	}

	(void)can_shell_rx_msgq_poll_submit(can_shell_rx_msgq_sh);
}

static const char *can_shell_state_to_string(enum can_state state)
{
	switch (state) {
	case CAN_STATE_ERROR_ACTIVE:
		return "error-active";
	case CAN_STATE_ERROR_WARNING:
		return "error-warning";
	case CAN_STATE_ERROR_PASSIVE:
		return "error-passive";
	case CAN_STATE_BUS_OFF:
		return "bus-off";
	case CAN_STATE_STOPPED:
		return "stopped";
	default:
		return "unknown";
	}
}

static void can_shell_print_capabilities(const struct shell *sh, can_mode_t cap)
{
	int bit;
	int i;

	for (bit = 0; bit < sizeof(cap) * 8; bit++) {
		/* Skip unset bits */
		if ((cap & BIT(bit)) == 0) {
			continue;
		}

		/* Lookup symbolic mode name */
		for (i = 0; i < ARRAY_SIZE(can_shell_mode_map); i++) {
			if (BIT(bit) == can_shell_mode_map[i].mode) {
				shell_fprintf(sh, SHELL_NORMAL, "%s ", can_shell_mode_map[i].name);
				break;
			}
		}

		if (i == ARRAY_SIZE(can_shell_mode_map)) {
			/* Symbolic name not found, use raw mode */
			shell_fprintf(sh, SHELL_NORMAL, "0x%08x ", (can_mode_t)BIT(bit));
		}
	}
}

static int cmd_can_start(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	shell_print(sh, "starting %s", argv[1]);

	err = can_start(dev);
	if (err != 0) {
		shell_error(sh, "failed to start CAN controller (err %d)", err);
		return err;
	}

	return 0;
}

static int cmd_can_stop(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	shell_print(sh, "stopping %s", argv[1]);

	err = can_stop(dev);
	if (err != 0) {
		shell_error(sh, "failed to stop CAN controller (err %d)", err);
		return err;
	}

	return 0;
}

static int cmd_can_show(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	struct can_bus_err_cnt err_cnt;
	enum can_state state;
	uint32_t max_bitrate = 0;
	int max_std_filters = 0;
	int max_ext_filters = 0;
	uint32_t core_clock;
	can_mode_t cap;
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	err = can_get_core_clock(dev, &core_clock);
	if (err != 0) {
		shell_error(sh, "failed to get CAN core clock (err %d)", err);
		return err;
	}

	err = can_get_max_bitrate(dev, &max_bitrate);
	if (err != 0 && err != -ENOSYS) {
		shell_error(sh, "failed to get maximum bitrate (err %d)", err);
		return err;
	}

	max_std_filters = can_get_max_filters(dev, false);
	if (max_std_filters < 0 && max_std_filters != -ENOSYS) {
		shell_error(sh, "failed to get maximum standard (11-bit) filters (err %d)", err);
		return err;
	}

	max_ext_filters = can_get_max_filters(dev, true);
	if (max_ext_filters < 0 && max_ext_filters != -ENOSYS) {
		shell_error(sh, "failed to get maximum extended (29-bit) filters (err %d)", err);
		return err;
	}

	err = can_get_capabilities(dev, &cap);
	if (err != 0) {
		shell_error(sh, "failed to get CAN controller capabilities (err %d)", err);
		return err;
	}

	err = can_get_state(dev, &state, &err_cnt);
	if (err != 0) {
		shell_error(sh, "failed to get CAN controller state (%d)", err);
		return err;
	}

	shell_print(sh, "core clock:      %d Hz", core_clock);
	shell_print(sh, "max bitrate:     %d bps", max_bitrate);
	shell_print(sh, "max std filters: %d", max_std_filters);
	shell_print(sh, "max ext filters: %d", max_ext_filters);

	shell_fprintf(sh, SHELL_NORMAL, "capabilities:    normal ");
	can_shell_print_capabilities(sh, cap);
	shell_fprintf(sh, SHELL_NORMAL, "\n");

	shell_print(sh, "state:           %s", can_shell_state_to_string(state));
	shell_print(sh, "rx errors:       %d", err_cnt.rx_err_cnt);
	shell_print(sh, "tx errors:       %d", err_cnt.tx_err_cnt);

	return 0;
}

static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	struct can_timing timing;
	uint16_t sample_pnt;
	uint32_t bitrate;
	char *endptr;
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	bitrate = (uint32_t)strtoul(argv[2], &endptr, 10);
	if (*endptr != '\0') {
		shell_error(sh, "failed to parse bitrate");
		return -EINVAL;
	}

	if (argc >= 4) {
		sample_pnt = (uint32_t)strtoul(argv[3], &endptr, 10);
		if (*endptr != '\0') {
			shell_error(sh, "failed to parse sample point");
			return -EINVAL;
		}

		timing.sjw = CAN_SJW_NO_CHANGE;

		err = can_calc_timing(dev, &timing, bitrate, sample_pnt);
		if (err < 0) {
			shell_error(sh, "failed to calculate timing for "
				    "bitrate %d bps, sample point %d.%d%% (err %d)",
				    bitrate, sample_pnt / 10, sample_pnt % 10, err);
			return err;
		}

		shell_print(sh, "setting bitrate to %d bps, sample point %d.%d%% "
			    "(+/- %d.%d%%)",
			    bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10);

		err = can_set_timing(dev, &timing);
		if (err != 0) {
			shell_error(sh, "failed to set timing (err %d)", err);
			return err;
		}
	} else {
		shell_print(sh, "setting bitrate to %d bps", bitrate);

		err = can_set_bitrate(dev, bitrate);
		if (err != 0) {
			shell_error(sh, "failed to set bitrate (err %d)", err);
			return err;
		}
	}

	return 0;
}

static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	struct can_timing timing;
	uint16_t sample_pnt;
	uint32_t bitrate;
	char *endptr;
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	bitrate = (uint32_t)strtoul(argv[2], &endptr, 10);
	if (*endptr != '\0') {
		shell_error(sh, "failed to parse data bitrate");
		return -EINVAL;
	}

	if (argc >= 4) {
		sample_pnt = (uint32_t)strtoul(argv[3], &endptr, 10);
		if (*endptr != '\0') {
			shell_error(sh, "failed to parse sample point");
			return -EINVAL;
		}

		timing.sjw = CAN_SJW_NO_CHANGE;

		err = can_calc_timing_data(dev, &timing, bitrate, sample_pnt);
		if (err < 0) {
			shell_error(sh, "failed to calculate timing for "
				    "data bitrate %d bps, sample point %d.%d%% (err %d)",
				    bitrate, sample_pnt / 10, sample_pnt % 10, err);
			return err;
		}

		shell_print(sh, "setting data bitrate to %d bps, sample point %d.%d%% "
			    "(+/- %d.%d%%)",
			    bitrate, sample_pnt / 10, sample_pnt % 10, err / 10, err % 10);

		err = can_set_timing_data(dev, &timing);
		if (err != 0) {
			shell_error(sh, "failed to set data timing (err %d)", err);
			return err;
		}
	} else {
		shell_print(sh, "setting data bitrate to %d bps", bitrate);

		err = can_set_bitrate_data(dev, bitrate);
		if (err != 0) {
			shell_error(sh, "failed to set data bitrate (err %d)", err);
			return err;
		}
	}

	return 0;
}

static int cmd_can_mode_set(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	can_mode_t mode = CAN_MODE_NORMAL;
	can_mode_t raw;
	char *endptr;
	int err;
	int i;
	int j;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	for (i = 2; i < argc; i++) {
		/* Lookup symbolic mode name */
		for (j = 0; j < ARRAY_SIZE(can_shell_mode_map); j++) {
			if (strcmp(argv[i], can_shell_mode_map[j].name) == 0) {
				mode |= can_shell_mode_map[j].mode;
				break;
			}
		}

		if (j == ARRAY_SIZE(can_shell_mode_map)) {
			/* Symbolic name not found, use raw mode if hex number */
			raw = (can_mode_t)strtoul(argv[i], &endptr, 16);
			if (*endptr == '\0') {
				mode |= raw;
				continue;
			}

			shell_error(sh, "failed to parse mode");
			return -EINVAL;
		}
	}

	shell_print(sh, "setting mode 0x%08x", mode);

	err = can_set_mode(dev, mode);
	if (err != 0) {
		shell_error(sh, "failed to set mode 0x%08x (err %d)", mode, err);
		return err;
	}

	return 0;
}

static int cmd_can_send(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	static unsigned int frame_counter;
	unsigned int frame_no;
	struct can_frame frame;
	uint32_t max_id;
	int argidx = 2;
	uint32_t val;
	char *endptr;
	int nbytes;
	int err;
	int i;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	/* Defaults */
	max_id = CAN_MAX_STD_ID;
	frame.flags = 0;
	frame.dlc = 0;

	/* Parse options */
	while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) {
		if (strcmp(argv[argidx], "--") == 0) {
			argidx++;
			break;
		} else if (strcmp(argv[argidx], "-e") == 0) {
			frame.flags |= CAN_FRAME_IDE;
			max_id = CAN_MAX_EXT_ID;
			argidx++;
		} else if (strcmp(argv[argidx], "-r") == 0) {
			frame.flags |= CAN_FRAME_RTR;
			argidx++;
		} else if (strcmp(argv[argidx], "-f") == 0) {
			frame.flags |= CAN_FRAME_FDF;
			argidx++;
		} else if (strcmp(argv[argidx], "-b") == 0) {
			frame.flags |= CAN_FRAME_BRS;
			argidx++;
		} else {
			shell_error(sh, "unsupported option %s", argv[argidx]);
			shell_help(sh);
			return SHELL_CMD_HELP_PRINTED;
		}
	}

	/* Parse CAN ID */
	if (argidx >= argc) {
		shell_error(sh, "missing CAN ID parameter");
		shell_help(sh);
		return SHELL_CMD_HELP_PRINTED;
	}

	val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
	if (*endptr != '\0') {
		shell_error(sh, "failed to parse CAN ID");
		return -EINVAL;
	}

	if (val > max_id) {
		shell_error(sh, "CAN ID 0x%0*x out of range",
			    (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3,
			    val);
		return -EINVAL;
	}

	frame.id = val;

	nbytes = argc - argidx;
	if (nbytes > ARRAY_SIZE(frame.data)) {
		shell_error(sh, "excessive amount of data (%d bytes)", nbytes);
		return -EINVAL;
	}

	frame.dlc = can_bytes_to_dlc(nbytes);

	/* Parse data */
	for (i = 0; i < nbytes; i++) {
		val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
		if (*endptr != '\0') {
			shell_error(sh, "failed to parse data %s", argv[argidx++]);
			return -EINVAL;
		}

		if (val > 0xff) {
			shell_error(sh, "data 0x%x out of range", val);
			return -EINVAL;
		}

		frame.data[i] = val;
	}

	err = can_shell_tx_msgq_poll_submit(sh);
	if (err != 0) {
		return err;
	}

	frame_no = frame_counter++;

	shell_print(sh, "enqueuing CAN frame #%u with %s (%d-bit) CAN ID 0x%0*x, "
		    "RTR %d, CAN-FD %d, BRS %d, DLC %d", frame_no,
		    (frame.flags & CAN_FRAME_IDE) != 0 ? "extended" : "standard",
		    (frame.flags & CAN_FRAME_IDE) != 0 ? 29 : 11,
		    (frame.flags & CAN_FRAME_IDE) != 0 ? 8 : 3, frame.id,
		    (frame.flags & CAN_FRAME_RTR) != 0 ? 1 : 0,
		    (frame.flags & CAN_FRAME_FDF) != 0 ? 1 : 0,
		    (frame.flags & CAN_FRAME_BRS) != 0 ? 1 : 0,
		    can_dlc_to_bytes(frame.dlc));

	err = can_send(dev, &frame, K_NO_WAIT, can_shell_tx_callback, UINT_TO_POINTER(frame_no));
	if (err != 0) {
		shell_error(sh, "failed to enqueue CAN frame #%u (err %d)", frame_no, err);
		return err;
	}

	return 0;
}

static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	struct can_filter filter;
	uint32_t max_id;
	int argidx = 2;
	uint32_t val;
	char *endptr;
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	/* Defaults */
	max_id = CAN_MAX_STD_ID;
	filter.flags = CAN_FILTER_DATA;

	/* Parse options */
	while (argidx < argc && strncmp(argv[argidx], "-", 1) == 0) {
		if (strcmp(argv[argidx], "--") == 0) {
			argidx++;
			break;
		} else if (strcmp(argv[argidx], "-e") == 0) {
			filter.flags |= CAN_FILTER_IDE;
			max_id = CAN_MAX_EXT_ID;
			argidx++;
		} else if (strcmp(argv[argidx], "-r") == 0) {
			filter.flags |= CAN_FILTER_RTR;
			argidx++;
		} else if (strcmp(argv[argidx], "-R") == 0) {
			filter.flags &= ~(CAN_FILTER_DATA);
			filter.flags |= CAN_FILTER_RTR;
			argidx++;
		} else {
			shell_error(sh, "unsupported argument %s", argv[argidx]);
			shell_help(sh);
			return SHELL_CMD_HELP_PRINTED;
		}
	}

	/* Parse CAN ID */
	if (argidx >= argc) {
		shell_error(sh, "missing CAN ID parameter");
		shell_help(sh);
		return SHELL_CMD_HELP_PRINTED;
	}

	val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
	if (*endptr != '\0') {
		shell_error(sh, "failed to parse CAN ID");
		return -EINVAL;
	}

	if (val > max_id) {
		shell_error(sh, "CAN ID 0x%0*x out of range",
			    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3,
			    val);
		return -EINVAL;
	}

	filter.id = val;

	if (argidx < argc) {
		/* Parse CAN ID mask */
		val = (uint32_t)strtoul(argv[argidx++], &endptr, 16);
		if (*endptr != '\0') {
			shell_error(sh, "failed to parse CAN ID mask");
			return -EINVAL;
		}

		if (val > max_id) {
			shell_error(sh, "CAN ID mask 0x%0*x out of range",
				    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3,
				    val);
			return -EINVAL;
		}

	} else {
		val = max_id;
	}

	filter.mask = val;

	err = can_shell_rx_msgq_poll_submit(sh);
	if (err != 0) {
		return err;
	}

	shell_print(sh, "adding filter with %s (%d-bit) CAN ID 0x%0*x, "
		    "CAN ID mask 0x%0*x, data frames %d, RTR frames %d",
		    (filter.flags & CAN_FILTER_IDE) != 0 ? "extended" : "standard",
		    (filter.flags & CAN_FILTER_IDE) != 0 ? 29 : 11,
		    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.id,
		    (filter.flags & CAN_FILTER_IDE) != 0 ? 8 : 3, filter.mask,
		    (filter.flags & CAN_FILTER_DATA) != 0 ? 1 : 0,
		    (filter.flags & CAN_FILTER_RTR) != 0 ? 1 : 0);

	err = can_add_rx_filter_msgq(dev, &can_shell_rx_msgq, &filter);
	if (err < 0) {
		shell_error(sh, "failed to add filter (err %d)", err);
		return err;
	}

	shell_print(sh, "filter ID: %d", err);

	return 0;
}

static int cmd_can_filter_remove(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	int filter_id;
	char *endptr;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	/* Parse filter ID */
	filter_id = (int)strtol(argv[2], &endptr, 10);
	if (*endptr != '\0') {
		shell_error(sh, "failed to parse filter ID");
		return -EINVAL;
	}

	shell_print(sh, "removing filter with ID %d", filter_id);
	can_remove_rx_filter(dev, filter_id);

	return 0;
}

static int cmd_can_recover(const struct shell *sh, size_t argc, char **argv)
{
	const struct device *dev = device_get_binding(argv[1]);
	k_timeout_t timeout = K_FOREVER;
	int millisec;
	char *endptr;
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "device %s not ready", argv[1]);
		return -ENODEV;
	}

	if (argc >= 3) {
		/* Parse timeout */
		millisec = (int)strtol(argv[2], &endptr, 10);
		if (*endptr != '\0') {
			shell_error(sh, "failed to parse timeout");
			return -EINVAL;
		}

		timeout = K_MSEC(millisec);
		shell_print(sh, "recovering, timeout %d ms", millisec);
	} else {
		shell_print(sh, "recovering, no timeout");
	}

	err = can_recover(dev, timeout);
	if (err != 0) {
		shell_error(sh, "failed to recover CAN controller from bus-off (err %d)", err);
		return err;
	}

	return 0;
}

static void cmd_can_device_name(size_t idx, struct shell_static_entry *entry)
{
	const struct device *dev = shell_device_lookup(idx, NULL);

	entry->syntax = (dev != NULL) ? dev->name : NULL;
	entry->handler = NULL;
	entry->help = NULL;
	entry->subcmd = NULL;
}

SHELL_DYNAMIC_CMD_CREATE(dsub_can_device_name, cmd_can_device_name);

static void cmd_can_mode(size_t idx, struct shell_static_entry *entry);

SHELL_DYNAMIC_CMD_CREATE(dsub_can_mode, cmd_can_mode);

static void cmd_can_mode(size_t idx, struct shell_static_entry *entry)
{
	if (idx < ARRAY_SIZE(can_shell_mode_map)) {
		entry->syntax = can_shell_mode_map[idx].name;

	} else {
		entry->syntax = NULL;
	}

	entry->handler = NULL;
	entry->help = NULL;
	entry->subcmd = &dsub_can_mode;
}

static void cmd_can_device_name_mode(size_t idx, struct shell_static_entry *entry)
{
	const struct device *dev = shell_device_lookup(idx, NULL);

	entry->syntax = (dev != NULL) ? dev->name : NULL;
	entry->handler = NULL;
	entry->help = NULL;
	entry->subcmd = &dsub_can_mode;
}

SHELL_DYNAMIC_CMD_CREATE(dsub_can_device_name_mode, cmd_can_device_name_mode);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_filter_cmds,
	SHELL_CMD_ARG(add, &dsub_can_device_name,
		"Add rx filter\n"
		"Usage: can filter add <device> [-e] [-r] [-R] <CAN ID> [CAN ID mask]\n"
		"-e  use extended (29-bit) CAN ID/CAN ID mask\n"
		"-r  also match Remote Transmission Request (RTR) frames\n"
		"-R  only match Remote Transmission Request (RTR) frames",
		cmd_can_filter_add, 3, 4),
	SHELL_CMD_ARG(remove, &dsub_can_device_name,
		"Remove rx filter\n"
		"Usage: can filter remove <device> <filter_id>",
		cmd_can_filter_remove, 3, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_cmds,
	SHELL_CMD_ARG(start, &dsub_can_device_name,
		"Start CAN controller\n"
		"Usage: can start <device>",
		cmd_can_start, 2, 0),
	SHELL_CMD_ARG(stop, &dsub_can_device_name,
		"Stop CAN controller\n"
		"Usage: can stop <device>",
		cmd_can_stop, 2, 0),
	SHELL_CMD_ARG(show, &dsub_can_device_name,
		"Show CAN controller information\n"
		"Usage: can show <device>",
		cmd_can_show, 2, 0),
	SHELL_CMD_ARG(bitrate, &dsub_can_device_name,
		"Set CAN controller bitrate and optional sample point\n"
		"Usage: can bitrate <device> <bitrate> [sample point]",
		cmd_can_bitrate_set, 3, 1),
	SHELL_COND_CMD_ARG(CONFIG_CAN_FD_MODE,
		dbitrate, &dsub_can_device_name,
		"Set CAN controller data phase bitrate and optional sample point\n"
		"Usage: can dbitrate <device> <data phase bitrate> [sample point]",
		cmd_can_dbitrate_set, 3, 1),
	SHELL_CMD_ARG(mode, &dsub_can_device_name_mode,
		"Set CAN controller mode\n"
		"Usage: can mode <device> <mode> [mode] [mode] [...]",
		cmd_can_mode_set, 3, SHELL_OPT_ARG_CHECK_SKIP),
	SHELL_CMD_ARG(send, &dsub_can_device_name,
		"Enqueue a CAN frame for sending\n"
		"Usage: can send <device> [-e] [-r] [-f] [-b] <CAN ID> [data] [...]\n"
		"-e  use extended (29-bit) CAN ID\n"
		"-r  send Remote Transmission Request (RTR) frame\n"
		"-f  use CAN-FD frame format\n"
		"-b  use CAN-FD Bit Rate Switching (BRS)",
		cmd_can_send, 3, SHELL_OPT_ARG_CHECK_SKIP),
	SHELL_CMD(filter, &sub_can_filter_cmds,
		"CAN rx filter commands\n"
		"Usage: can filter <add|remove> <device> ...",
		NULL),
	SHELL_EXPR_CMD_ARG(!IS_ENABLED(CONFIG_CAN_AUTO_BUS_OFF_RECOVERY),
		recover, &dsub_can_device_name,
		"Recover CAN controller from bus-off state\n"
		"Usage: can recover <device> [timeout ms]",
		cmd_can_recover, 2, 1),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(can, &sub_can_cmds, "CAN controller commands", NULL);
