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

/**
 * @file
 *
 * PPP driver using uart_pipe. This is meant for network connectivity between
 * two network end points.
 */

#define LOG_LEVEL CONFIG_NET_PPP_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(net_ppp, LOG_LEVEL);

#include <stdio.h>

#include <kernel.h>

#include <stdbool.h>
#include <errno.h>
#include <stddef.h>
#include <net/ppp.h>
#include <net/buf.h>
#include <net/net_pkt.h>
#include <net/net_if.h>
#include <net/net_core.h>
#include <console/uart_pipe.h>
#include <sys/crc.h>

#include "../../subsys/net/ip/net_stats.h"
#include "../../subsys/net/ip/net_private.h"

#define UART_BUF_LEN CONFIG_NET_PPP_UART_PIPE_BUF_LEN

enum ppp_driver_state {
	STATE_HDLC_FRAME_START,
	STATE_HDLC_FRAME_ADDRESS,
	STATE_HDLC_FRAME_DATA,
};

struct ppp_driver_context {
	struct net_if *iface;

	/* This net_pkt contains pkt that is being read */
	struct net_pkt *pkt;

	/* How much free space we have in the net_pkt */
	size_t available;

	/* ppp data is read into this buf */
	u8_t buf[UART_BUF_LEN];

	/* ppp buf use when sending data */
	u8_t send_buf[UART_BUF_LEN];

	u8_t mac_addr[6];
	struct net_linkaddr ll_addr;

#if defined(CONFIG_NET_STATISTICS_PPP)
	struct net_stats_ppp stats;
#endif

	enum ppp_driver_state state;

	u8_t init_done : 1;
	u8_t next_escaped : 1;
};

static struct ppp_driver_context ppp_driver_context_data;

static int ppp_save_byte(struct ppp_driver_context *ppp, u8_t byte)
{
	int ret;

	if (!ppp->pkt) {
		ppp->pkt = net_pkt_rx_alloc_with_buffer(
			ppp->iface,
			CONFIG_NET_BUF_DATA_SIZE,
			AF_UNSPEC, 0, K_NO_WAIT);
		if (!ppp->pkt) {
			LOG_ERR("[%p] cannot allocate pkt", ppp);
			return -ENOMEM;
		}

		net_pkt_cursor_init(ppp->pkt);

		ppp->available = net_pkt_available_buffer(ppp->pkt);
	}

	/* Extra debugging can be enabled separately if really
	 * needed. Normally it would just print too much data.
	 */
	if (0) {
		LOG_DBG("Saving byte %02x", byte);
	}

	/* This is not very intuitive but we must allocate new buffer
	 * before we write a byte to last available cursor position.
	 */
	if (ppp->available == 1) {
		ret = net_pkt_alloc_buffer(ppp->pkt,
					   CONFIG_NET_BUF_DATA_SIZE,
					   AF_UNSPEC, K_NO_WAIT);
		if (ret < 0) {
			LOG_ERR("[%p] cannot allocate new data buffer", ppp);
			goto out_of_mem;
		}

		ppp->available = net_pkt_available_buffer(ppp->pkt);
	}

	if (ppp->available) {
		ret = net_pkt_write_u8(ppp->pkt, byte);
		if (ret < 0) {
			LOG_ERR("[%p] Cannot write to pkt %p (%d)",
				ppp, ppp->pkt, ret);
			goto out_of_mem;
		}

		ppp->available--;
	}

	return 0;

out_of_mem:
	net_pkt_unref(ppp->pkt);
	ppp->pkt = NULL;
	return -ENOMEM;
}

static const char *ppp_driver_state_str(enum ppp_driver_state state)
{
#if (CONFIG_NET_PPP_LOG_LEVEL >= LOG_LEVEL_DBG)
	switch (state) {
	case STATE_HDLC_FRAME_START:
		return "START";
	case STATE_HDLC_FRAME_ADDRESS:
		return "ADDRESS";
	case STATE_HDLC_FRAME_DATA:
		return "DATA";
	}
#else
	ARG_UNUSED(state);
#endif

	return "";
}

static void ppp_change_state(struct ppp_driver_context *ctx,
			     enum ppp_driver_state new_state)
{
	NET_ASSERT(ctx);

	if (ctx->state == new_state) {
		return;
	}

	NET_ASSERT(new_state >= STATE_HDLC_FRAME_START &&
		   new_state <= STATE_HDLC_FRAME_DATA);

	NET_DBG("[%p] state %s (%d) => %s (%d)",
		ctx, ppp_driver_state_str(ctx->state), ctx->state,
		ppp_driver_state_str(new_state), new_state);

	ctx->state = new_state;
}

static int ppp_input_byte(struct ppp_driver_context *ppp, u8_t byte)
{
	int ret = -EAGAIN;

	switch (ppp->state) {
	case STATE_HDLC_FRAME_START:
		/* Synchronizing the flow with HDLC flag field */
		if (byte == 0x7e) {
			/* Note that we do not save the sync flag */
			LOG_DBG("Sync byte (0x%02x) start", byte);
			ppp_change_state(ppp, STATE_HDLC_FRAME_ADDRESS);
		}

		break;

	case STATE_HDLC_FRAME_ADDRESS:
		if (byte != 0xff) {
			/* Check if we need to sync again */
			if (byte == 0x7e) {
				/* Just skip to the start of the pkt byte */
				return -EAGAIN;
			}

			LOG_DBG("Invalid (0x%02x) byte, expecting Address",
				byte);

			/* If address is != 0xff, then ignore this
			 * frame. RFC 1662 ch 3.1
			 */
			ppp_change_state(ppp, STATE_HDLC_FRAME_START);
		} else {
			LOG_DBG("Address byte (0x%02x) start", byte);

			ppp_change_state(ppp, STATE_HDLC_FRAME_DATA);

			/* Save the address field so that we can calculate
			 * the FCS. The address field will not be passed
			 * to upper stack.
			 */
			ret = ppp_save_byte(ppp, byte);
			if (ret < 0) {
				ppp_change_state(ppp, STATE_HDLC_FRAME_START);
			}

			ret = -EAGAIN;
		}

		break;

	case STATE_HDLC_FRAME_DATA:
		/* If the next frame starts, then send this one
		 * up in the network stack.
		 */
		if (byte == 0x7e) {
			LOG_DBG("End of pkt (0x%02x)", byte);
			ppp_change_state(ppp, STATE_HDLC_FRAME_ADDRESS);
			ret = 0;
		} else {
			if (byte == 0x7d) {
				/* RFC 1662, ch. 4.2 */
				ppp->next_escaped = true;
				break;
			}

			if (ppp->next_escaped) {
				/* RFC 1662, ch. 4.2 */
				byte ^= 0x20;
				ppp->next_escaped = false;
			}

			ret = ppp_save_byte(ppp, byte);
			if (ret < 0) {
				ppp_change_state(ppp, STATE_HDLC_FRAME_START);
			}

			ret = -EAGAIN;
		}

		break;

	default:
		LOG_DBG("[%p] Invalid state %d", ppp, ppp->state);
		break;
	}

	return ret;
}

static bool ppp_check_fcs(struct ppp_driver_context *ppp)
{
	struct net_buf *buf;
	u16_t crc;

	buf = ppp->pkt->buffer;
	if (!buf) {
		return false;
	}

	crc = crc16_ccitt(0xffff, buf->data, buf->len);

	buf = buf->frags;

	while (buf) {
		crc = crc16_ccitt(crc, buf->data, buf->len);
		buf = buf->frags;
	}

	if (crc != 0xf0b8) {
		LOG_DBG("Invalid FCS (0x%x)", crc);
#if defined(CONFIG_NET_STATISTICS_PPP)
		ppp->stats.chkerr++;
#endif
		return false;
	}

	return true;
}

static void ppp_process_msg(struct ppp_driver_context *ppp)
{
	if (LOG_LEVEL >= LOG_LEVEL_DBG) {
		net_pkt_hexdump(ppp->pkt, "recv ppp");
	}

	if (IS_ENABLED(CONFIG_NET_PPP_VERIFY_FCS) && !ppp_check_fcs(ppp)) {
#if defined(CONFIG_NET_STATISTICS_PPP)
		ppp->stats.drop++;
		ppp->stats.pkts.rx++;
#endif
		net_pkt_unref(ppp->pkt);
	} else {
		/* Remove the Address (0xff), Control (0x03) and
		 * FCS fields (16-bit) as the PPP L2 layer does not need
		 * those bytes.
		 */
		u16_t addr_and_ctrl = net_buf_pull_be16(ppp->pkt->buffer);

		/* Currently we do not support compressed Address and Control
		 * fields so they must always be present.
		 */
		if (addr_and_ctrl != (0xff << 8 | 0x03)) {
#if defined(CONFIG_NET_STATISTICS_PPP)
			ppp->stats.drop++;
			ppp->stats.pkts.rx++;
#endif
			net_pkt_unref(ppp->pkt);
		} else {
			/* Skip FCS bytes (2) */
			net_buf_frag_last(ppp->pkt->buffer)->len -= 2;

			/* Make sure we now start reading from PPP header in
			 * PPP L2 recv()
			 */
			net_pkt_cursor_init(ppp->pkt);
			net_pkt_set_overwrite(ppp->pkt, true);

			if (net_recv_data(ppp->iface, ppp->pkt) < 0) {
				net_pkt_unref(ppp->pkt);
			}
		}
	}

	ppp->pkt = NULL;
}

static u8_t *ppp_recv_cb(u8_t *buf, size_t *off)
{
	struct ppp_driver_context *ppp =
		CONTAINER_OF(buf, struct ppp_driver_context, buf);
	size_t i, len = *off;

	for (i = 0; i < *off; i++) {
		if (0) {
			/* Extra debugging can be enabled separately if really
			 * needed. Normally it would just print too much data.
			 */
			LOG_DBG("[%zd] %02x", i, buf[i]);
		}

		if (ppp_input_byte(ppp, buf[i]) == 0) {
			/* Ignore empty or too short frames */
			if (ppp->pkt && net_pkt_get_len(ppp->pkt) > 3) {
				ppp_process_msg(ppp);
				break;
			}
		}
	}

	if (i == *off) {
		*off = 0;
	} else {
		*off = len - i - 1;

		memmove(&buf[0], &buf[i + 1], *off);
	}

	return buf;
}

#if defined(CONFIG_NET_TEST)
void ppp_driver_feed_data(u8_t *data, int data_len)
{
	struct ppp_driver_context *ppp = &ppp_driver_context_data;
	size_t recv_off = 0;

	/* We are expecting that the tests are feeding data in large
	 * chunks so we can reset the uart buffer here.
	 */
	memset(ppp->buf, 0, UART_BUF_LEN);

	ppp_change_state(ppp, STATE_HDLC_FRAME_START);

	while (data_len > 0) {
		int data_to_copy = MIN(data_len, UART_BUF_LEN);
		int remaining;

		LOG_DBG("Feeding %d bytes", data_to_copy);

		memcpy(ppp->buf, data, data_to_copy);

		recv_off = data_to_copy;

		(void)ppp_recv_cb(ppp->buf, &recv_off);

		remaining = data_to_copy - recv_off;

		LOG_DBG("We copied %d bytes", remaining);

		data_len -= remaining;
		data += remaining;
	}
}
#endif

static bool calc_fcs(struct net_pkt *pkt, u16_t *fcs, u16_t protocol)
{
	struct net_buf *buf;
	u16_t crc;
	u16_t c;

	buf = pkt->buffer;
	if (!buf) {
		return false;
	}

	/* HDLC Address and Control fields */
	c = sys_cpu_to_be16(0xff << 8 | 0x03);

	crc = crc16_ccitt(0xffff, (const u8_t *)&c, sizeof(c));

	if (protocol > 0) {
		crc = crc16_ccitt(crc, (const u8_t *)&protocol,
				  sizeof(protocol));
	}

	while (buf) {
		crc = crc16_ccitt(crc, buf->data, buf->len);
		buf = buf->frags;
	}

	crc ^= 0xffff;
	*fcs = crc;

	return true;
}

static int ppp_send_flush(struct ppp_driver_context *ppp, int off)
{
	if (!IS_ENABLED(CONFIG_NET_TEST)) {
		uart_pipe_send(ppp->send_buf, off);
	}

	return 0;
}

static int ppp_send_bytes(struct ppp_driver_context *ppp,
			  const u8_t *data, int len, int off)
{
	int i;

	for (i = 0; i < len; i++) {
		ppp->send_buf[off++] = data[i];

		if (off >= sizeof(ppp->send_buf)) {
			off = ppp_send_flush(ppp, off);
		}
	}

	return off;
}

static u16_t ppp_escape_byte(u8_t byte, int *offset)
{
	if (byte == 0x7e || byte == 0x7d || byte < 0x20) {
		*offset = 0;
		return (0x7d << 8) | (byte ^ 0x20);
	}

	*offset = 1;
	return byte;
}

static int ppp_send(struct device *dev, struct net_pkt *pkt)
{
	struct ppp_driver_context *ppp = dev->driver_data;
	struct net_buf *buf = pkt->buffer;
	u16_t protocol = 0;
	int send_off = 0;
	u32_t sync_addr_ctrl;
	u16_t fcs, escaped;
	u8_t byte;
	int i, offset;

#if defined(CONFIG_NET_TEST)
	return 0;
#endif

	ARG_UNUSED(dev);

	if (!buf) {
		/* No data? */
		return -ENODATA;
	}

	/* If the packet is a normal network packet, we must add the protocol
	 * value here.
	 */
	if (!net_pkt_is_ppp(pkt)) {
		if (net_pkt_family(pkt) == AF_INET) {
			protocol = htons(PPP_IP);
		} else if (net_pkt_family(pkt) == AF_INET6) {
			protocol = htons(PPP_IPV6);
		} else {
			return -EPROTONOSUPPORT;
		}
	}

	if (!calc_fcs(pkt, &fcs, protocol)) {
		return -ENOMEM;
	}

	/* Sync, Address & Control fields */
	sync_addr_ctrl = sys_cpu_to_be32(0x7e << 24 | 0xff << 16 |
					 0x7d << 8 | 0x23);
	send_off = ppp_send_bytes(ppp, (const u8_t *)&sync_addr_ctrl,
				  sizeof(sync_addr_ctrl), send_off);

	if (protocol > 0) {
		escaped = htons(ppp_escape_byte(protocol, &offset));
		send_off = ppp_send_bytes(ppp, (u8_t *)&escaped + offset,
					  offset ? 1 : 2,
					  send_off);

		escaped = htons(ppp_escape_byte(protocol >> 8, &offset));
		send_off = ppp_send_bytes(ppp, (u8_t *)&escaped + offset,
					  offset ? 1 : 2,
					  send_off);
	}

	/* Note that we do not print the first four bytes and FCS bytes at the
	 * end so that we do not need to allocate separate net_buf just for
	 * that purpose.
	 */
	if (LOG_LEVEL >= LOG_LEVEL_DBG) {
		net_pkt_hexdump(pkt, "send ppp");
	}

	while (buf) {
		for (i = 0; i < buf->len; i++) {
			/* Escape illegal bytes */
			escaped = htons(ppp_escape_byte(buf->data[i], &offset));
			send_off = ppp_send_bytes(ppp,
						  (u8_t *)&escaped + offset,
						  offset ? 1 : 2,
						  send_off);
		}

		buf = buf->frags;
	}

	escaped = htons(ppp_escape_byte(fcs, &offset));
	send_off = ppp_send_bytes(ppp, (u8_t *)&escaped + offset,
				  offset ? 1 : 2,
				  send_off);

	escaped = htons(ppp_escape_byte(fcs >> 8, &offset));
	send_off = ppp_send_bytes(ppp, (u8_t *)&escaped + offset,
				  offset ? 1 : 2,
				  send_off);

	byte = 0x7e;
	send_off = ppp_send_bytes(ppp, &byte, 1, send_off);

	(void)ppp_send_flush(ppp, send_off);

	return 0;
}

static int ppp_driver_init(struct device *dev)
{
	struct ppp_driver_context *ppp = dev->driver_data;

	LOG_DBG("[%p] dev %p", ppp, dev);

	ppp->pkt = NULL;
	ppp_change_state(ppp, STATE_HDLC_FRAME_START);

	return 0;
}

static inline struct net_linkaddr *ppp_get_mac(struct ppp_driver_context *ppp)
{
	ppp->ll_addr.addr = ppp->mac_addr;
	ppp->ll_addr.len = sizeof(ppp->mac_addr);

	return &ppp->ll_addr;
}

static void ppp_iface_init(struct net_if *iface)
{
	struct ppp_driver_context *ppp = net_if_get_device(iface)->driver_data;
	struct net_linkaddr *ll_addr;

	LOG_DBG("[%p] iface %p", ppp, iface);

	net_ppp_init(iface);

	if (ppp->init_done) {
		return;
	}

	ppp->init_done = true;
	ppp->iface = iface;

	/* The mac address is not really used but network interface expects
	 * to find one.
	 */
	ll_addr = ppp_get_mac(ppp);

	if (CONFIG_PPP_MAC_ADDR[0] != 0) {
		if (net_bytes_from_str(ppp->mac_addr, sizeof(ppp->mac_addr),
				       CONFIG_PPP_MAC_ADDR) < 0) {
			goto use_random_mac;
		}
	} else {
use_random_mac:
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		ppp->mac_addr[0] = 0x00;
		ppp->mac_addr[1] = 0x00;
		ppp->mac_addr[2] = 0x5E;
		ppp->mac_addr[3] = 0x00;
		ppp->mac_addr[4] = 0x53;
		ppp->mac_addr[5] = sys_rand32_get();
	}

	net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len,
			     NET_LINK_ETHERNET);

	memset(ppp->buf, 0, sizeof(ppp->buf));

	/* We do not use uart_pipe for unit tests as the unit test has its
	 * own handling of UART. See tests/net/ppp/driver for details.
	 */
	if (!IS_ENABLED(CONFIG_NET_TEST)) {
		uart_pipe_register(ppp->buf, sizeof(ppp->buf), ppp_recv_cb);
	}
}

#if defined(CONFIG_NET_STATISTICS_PPP)
static struct net_stats_ppp *ppp_get_stats(struct device *dev)
{
	struct ppp_driver_context *context = dev->driver_data;

	return &context->stats;
}
#endif

static int ppp_start(struct device *dev)
{
	struct ppp_driver_context *context = dev->driver_data;

	net_ppp_carrier_on(context->iface);

	return 0;
}

static int ppp_stop(struct device *dev)
{
	struct ppp_driver_context *context = dev->driver_data;

	net_ppp_carrier_off(context->iface);

	return 0;
}

static const struct ppp_api ppp_if_api = {
	.iface_api.init = ppp_iface_init,

	.send = ppp_send,
	.start = ppp_start,
	.stop = ppp_stop,
#if defined(CONFIG_NET_STATISTICS_PPP)
	.get_stats = ppp_get_stats,
#endif
};

NET_DEVICE_INIT(ppp, CONFIG_NET_PPP_DRV_NAME, ppp_driver_init,
		&ppp_driver_context_data, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &ppp_if_api,
		PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), PPP_MTU);
