/*
 * Copyright (c) 2019 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 */

/* CANBUS related functions that are generic in all the drivers. */

#include <net/net_pkt.h>
#include <net/socket_can.h>

#ifndef ZEPHYR_DRIVERS_CAN_SOCKET_CAN_GENERIC_H_
#define ZEPHYR_DRIVERS_CAN_SOCKET_CAN_GENERIC_H_

#define SOCKET_CAN_NAME_0 "SOCKET_CAN_0"
#define SOCKET_CAN_NAME_1 "SOCKET_CAN_1"
#define SOCKET_CAN_NAME_2 "SOCKET_CAN_2"
#define SEND_TIMEOUT K_MSEC(100)
#define RX_THREAD_STACK_SIZE 512
#define RX_THREAD_PRIORITY 2
#define BUF_ALLOC_TIMEOUT K_MSEC(50)

/* TODO: make msgq size configurable */
CAN_DEFINE_MSGQ(socket_can_msgq, 5);
K_KERNEL_STACK_DEFINE(rx_thread_stack, RX_THREAD_STACK_SIZE);

struct socket_can_context {
	const struct device *can_dev;
	struct net_if *iface;
	struct k_msgq *msgq;

	/* TODO: remove the thread and push data to net directly from rx isr */
	k_tid_t rx_tid;
	struct k_thread rx_thread_data;
};

static inline void socket_can_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct socket_can_context *socket_context = dev->data;

	socket_context->iface = iface;

	LOG_DBG("Init CAN interface %p dev %p", iface, dev);
}

static inline void tx_irq_callback(int error, void *arg)
{
	char *caller_str = (char *)arg;
	if (error != 0) {
		LOG_DBG("TX error from %s! error-code: %d",
			caller_str, error);
	}
}

/* This is called by net_if.c when packet is about to be sent */
static inline int socket_can_send(const struct device *dev,
				  struct net_pkt *pkt)
{
	struct socket_can_context *socket_context = dev->data;
	int ret;

	if (net_pkt_family(pkt) != AF_CAN) {
		return -EPFNOSUPPORT;
	}

	ret = can_send(socket_context->can_dev,
		       (struct zcan_frame *)pkt->frags->data,
		       SEND_TIMEOUT, tx_irq_callback, "socket_can_send");
	if (ret) {
		LOG_DBG("Cannot send socket CAN msg (%d)", ret);
	}

	/* If something went wrong, then we need to return negative value to
	 * net_if.c:net_if_tx() so that the net_pkt will get released.
	 */
	return -ret;
}

static inline int socket_can_setsockopt(const struct device *dev, void *obj,
					int level, int optname,
					const void *optval, socklen_t optlen)
{
	struct socket_can_context *socket_context = dev->data;
	struct net_context *ctx = obj;
	int ret;

	if (level != SOL_CAN_RAW && optname != CAN_RAW_FILTER) {
		errno = EINVAL;
		return -1;
	}

	__ASSERT_NO_MSG(optlen == sizeof(struct zcan_filter));

	ret = can_attach_msgq(socket_context->can_dev, socket_context->msgq,
			      optval);
	if (ret == CAN_NO_FREE_FILTER) {
		errno = ENOSPC;
		return -1;
	}

	net_context_set_filter_id(ctx, ret);

	return 0;
}

static inline void socket_can_close(const struct device *dev, int filter_id)
{
	struct socket_can_context *socket_context = dev->data;

	can_detach(socket_context->can_dev, filter_id);
}

static struct canbus_api socket_can_api = {
	.iface_api.init = socket_can_iface_init,
	.send = socket_can_send,
	.close = socket_can_close,
	.setsockopt = socket_can_setsockopt,
};

static inline void rx_thread(void *ctx, void *unused1, void *unused2)
{
	struct socket_can_context *socket_context = ctx;
	struct net_pkt *pkt;
	struct zcan_frame msg;
	int ret;

	ARG_UNUSED(unused1);
	ARG_UNUSED(unused2);

	while (1) {
		k_msgq_get((struct k_msgq *)socket_context->msgq, &msg,
			   K_FOREVER);

		pkt = net_pkt_rx_alloc_with_buffer(socket_context->iface,
						   sizeof(msg),
						   AF_CAN, 0,
						   BUF_ALLOC_TIMEOUT);
		if (!pkt) {
			LOG_ERR("Failed to obtain RX buffer");
			continue;
		}

		if (net_pkt_write(pkt, (void *)&msg, sizeof(msg))) {
			LOG_ERR("Failed to append RX data");
			net_pkt_unref(pkt);
			continue;
		}

		ret = net_recv_data(socket_context->iface, pkt);
		if (ret < 0) {
			net_pkt_unref(pkt);
		}
	}
}

#endif /* ZEPHYR_DRIVERS_CAN_SOCKET_CAN_GENERIC_H_ */
