/*
 * 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[] = {
	/* zephyr-keep-sorted-start */
	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("manual-recovery", CAN_MODE_MANUAL_RECOVERY),
	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),
	/* zephyr-keep-sorted-stop */
};

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%c  ",
		      (frame->flags & CAN_FRAME_BRS) == 0 ? '-' : 'B',
		      (frame->flags & CAN_FRAME_ESI) == 0 ? '-' : 'P');
#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_extended_modes(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]);
	const struct device *phy;
	const struct can_timing *timing_min;
	const struct can_timing *timing_max;
	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_extended_modes(sh, cap);
	shell_fprintf(sh, SHELL_NORMAL, "\n");

	shell_fprintf(sh, SHELL_NORMAL, "mode:            normal ");
	can_shell_print_extended_modes(sh, can_get_mode(dev));
	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);

	timing_min = can_get_timing_min(dev);
	timing_max = can_get_timing_max(dev);

	shell_print(sh, "timing:          sjw %u..%u, prop_seg %u..%u, "
		    "phase_seg1 %u..%u, phase_seg2 %u..%u, prescaler %u..%u",
		    timing_min->sjw, timing_max->sjw,
		    timing_min->prop_seg, timing_max->prop_seg,
		    timing_min->phase_seg1, timing_max->phase_seg1,
		    timing_min->phase_seg2, timing_max->phase_seg2,
		    timing_min->prescaler, timing_max->prescaler);

	if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (cap & CAN_MODE_FD) != 0) {
		timing_min = can_get_timing_data_min(dev);
		timing_max = can_get_timing_data_max(dev);

		shell_print(sh, "timing data:     sjw %u..%u, prop_seg %u..%u, "
			    "phase_seg1 %u..%u, phase_seg2 %u..%u, prescaler %u..%u",
			    timing_min->sjw, timing_max->sjw,
			    timing_min->prop_seg, timing_max->prop_seg,
			    timing_min->phase_seg1, timing_max->phase_seg1,
			    timing_min->phase_seg2, timing_max->phase_seg2,
			    timing_min->prescaler, timing_max->prescaler);
	}

	phy = can_get_transceiver(dev);
	shell_print(sh, "transceiver:     %s", phy != NULL ? phy->name : "passive/none");

#ifdef CONFIG_CAN_STATS
	shell_print(sh, "statistics:");
	shell_print(sh, "  bit errors:    %u", can_stats_get_bit_errors(dev));
	shell_print(sh, "    bit0 errors: %u", can_stats_get_bit0_errors(dev));
	shell_print(sh, "    bit1 errors: %u", can_stats_get_bit1_errors(dev));
	shell_print(sh, "  stuff errors:  %u", can_stats_get_stuff_errors(dev));
	shell_print(sh, "  crc errors:    %u", can_stats_get_crc_errors(dev));
	shell_print(sh, "  form errors:   %u", can_stats_get_form_errors(dev));
	shell_print(sh, "  ack errors:    %u", can_stats_get_ack_errors(dev));
	shell_print(sh, "  rx overruns:   %u", can_stats_get_rx_overruns(dev));
#endif /* CONFIG_CAN_STATS */

	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 = { 0 };
	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;
		}

		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;
		}

		if (argc >= 5) {
			/* Overwrite calculated default SJW with user-provided value */
			timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10);
			if (*endptr != '\0') {
				shell_error(sh, "failed to parse SJW");
				return -EINVAL;
			}
		}

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

		LOG_DBG("sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, prescaler %u",
			timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2,
			timing.prescaler);

		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 = { 0 };
	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;
		}

		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;
		}

		if (argc >= 5) {
			/* Overwrite calculated default SJW with user-provided value */
			timing.sjw = (uint16_t)strtoul(argv[4], &endptr, 10);
			if (*endptr != '\0') {
				shell_error(sh, "failed to parse SJW");
				return -EINVAL;
			}
		}

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

		LOG_DBG("sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, prescaler %u",
			timing.sjw, timing.prop_seg, timing.phase_seg1, timing.phase_seg2,
			timing.prescaler);

		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 can_shell_parse_timing(const struct shell *sh, size_t argc, char **argv,
				  struct can_timing *timing)
{
	char *endptr;

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

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

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

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

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

	return 0;
}

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

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

	err = can_shell_parse_timing(sh, argc, argv, &timing);
	if (err < 0) {
		return err;
	}

	shell_print(sh, "setting timing to sjw %u, prop_seg %u, phase_seg1 %u, phase_seg2 %u, "
		    "prescaler %u", timing.sjw, timing.prop_seg, timing.phase_seg1,
		    timing.phase_seg2, timing.prescaler);

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

	return 0;
}

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

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

	err = can_shell_parse_timing(sh, argc, argv, &timing);
	if (err < 0) {
		return err;
	}

	shell_print(sh, "setting data phase timing to sjw %u, prop_seg %u, phase_seg1 %u, "
		    "phase_seg2 %u, prescaler %u", timing.sjw, timing.prop_seg, timing.phase_seg1,
		    timing.phase_seg2, timing.prescaler);

	err = can_set_timing_data(dev, &timing);
	if (err != 0) {
		shell_error(sh, "failed to set data phase timing (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 = 0U;

	/* 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 {
			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",
		    (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);

	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] <CAN ID> [CAN ID mask]\n"
		"-e  use extended (29-bit) CAN ID/CAN ID mask\n",
		cmd_can_filter_add, 3, 2),
	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 (sample point and SJW optional)\n"
		"Usage: can bitrate <device> <bitrate> [sample point] [sjw]",
		cmd_can_bitrate_set, 3, 2),
	SHELL_COND_CMD_ARG(CONFIG_CAN_FD_MODE,
		dbitrate, &dsub_can_device_name,
		"Set CAN controller data phase bitrate (sample point and SJW optional)\n"
		"Usage: can dbitrate <device> <data phase bitrate> [sample point] [sjw]",
		cmd_can_dbitrate_set, 3, 2),
	SHELL_CMD_ARG(timing, &dsub_can_device_name,
		"Set CAN controller timing\n"
		"Usage: can timing <device> <sjw> <prop_seg> <phase_seg1> <phase_seg2> <prescaler>",
		cmd_can_timing_set, 7, 0),
	SHELL_COND_CMD_ARG(CONFIG_CAN_FD_MODE,
		dtiming, &dsub_can_device_name,
		"Set CAN controller data phase timing\n"
		"Usage: can dtiming <device> <sjw> <prop_seg> <phase_seg1> <phase_seg2> <prescaler>",
		cmd_can_dtiming_set, 7, 0),
	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_COND_CMD_ARG(CONFIG_CAN_MANUAL_RECOVERY_MODE,
		recover, &dsub_can_device_name,
		"Manually 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);
