/* udp.c - UDP specific code for throughput server */

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

#if 1
#define SYS_LOG_DOMAIN "tp-server"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif

#include <zephyr.h>
#include <errno.h>
#include <stdio.h>

#include <net/net_pkt.h>
#include <net/net_core.h>
#include <net/net_context.h>
#include <net/udp.h>

#include <net/net_app.h>

#include "common.h"

#define STATS_CHECK 1000

#define TYPE_SEQ_NUM 42

struct header {
	unsigned char type;
	unsigned char len;
	unsigned char value[0];
} __packed;

static struct net_app_ctx udp;

/* Note that both tcp and udp can share the same pool but in this
 * example the UDP context and TCP context have separate pools.
 */
#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
NET_PKT_SLAB_DEFINE(echo_tx_udp, 100);
NET_PKT_DATA_POOL_DEFINE(echo_data_udp, 200);

static struct k_mem_slab *tx_udp_slab(void)
{
	return &echo_tx_udp;
}

static struct net_buf_pool *data_udp_pool(void)
{
	return &echo_data_udp;
}
#else
#define tx_udp_slab NULL
#define data_udp_pool NULL
#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */

static inline void set_dst_addr(sa_family_t family,
				struct net_pkt *pkt,
				struct sockaddr *dst_addr)
{
	struct net_udp_hdr hdr, *udp_hdr;

	udp_hdr = net_udp_get_hdr(pkt, &hdr);
	if (!udp_hdr) {
		return;
	}

#if defined(CONFIG_NET_IPV6)
	if (family == AF_INET6) {
		net_ipaddr_copy(&net_sin6(dst_addr)->sin6_addr,
				&NET_IPV6_HDR(pkt)->src);
		net_sin6(dst_addr)->sin6_family = AF_INET6;
		net_sin6(dst_addr)->sin6_port = udp_hdr->src_port;
	}
#endif /* CONFIG_NET_IPV6) */

#if defined(CONFIG_NET_IPV4)
	if (family == AF_INET) {
		net_ipaddr_copy(&net_sin(dst_addr)->sin_addr,
				&NET_IPV4_HDR(pkt)->src);
		net_sin(dst_addr)->sin_family = AF_INET;
		net_sin(dst_addr)->sin_port = udp_hdr->src_port;
	}
#endif /* CONFIG_NET_IPV6) */
}

static void udp_received(struct net_app_ctx *ctx,
			 struct net_pkt *pkt,
			 int status,
			 void *user_data)
{
	static char dbg[MAX_DBG_PRINT + 1];
	static u32_t prev_seq;
	static u32_t count;
	struct sockaddr dst_addr;
	struct header *hdr;
	sa_family_t family = net_pkt_family(pkt);
	socklen_t dst_len;
	u32_t pkt_len;
#if defined(SEND_REPLY)
	struct net_pkt *reply_pkt;
	int ret;
#endif

	snprintk(dbg, MAX_DBG_PRINT, "UDP IPv%c",
		 family == AF_INET6 ? '6' : '4');

	if (family == AF_INET6) {
		dst_len = sizeof(struct sockaddr_in6);
	} else {
		dst_len = sizeof(struct sockaddr_in);
	}

	set_dst_addr(family, pkt, &dst_addr);

#if defined(SEND_REPLY)
	reply_pkt = build_reply_pkt(dbg, ctx, pkt);
#endif

	pkt_len = net_pkt_appdatalen(pkt);

	tp_stats.bytes.recv += pkt_len;
	tp_stats.pkts.recv++;

	hdr = (struct header *)net_pkt_appdata(pkt);
	if (hdr->type == TYPE_SEQ_NUM) {
		u32_t seq;

		memcpy(&seq, hdr->value, sizeof(seq));
		seq = ntohl(seq);

		if (seq && prev_seq && seq != (prev_seq + 1)) {
			tp_stats.pkts.dropped += (seq - prev_seq);
		}

		prev_seq = seq;
	}

	net_pkt_unref(pkt);

#if defined(SEND_REPLY)
	if (!reply_pkt) {
		return;
	}

	pkt_len = net_pkt_appdatalen(reply_pkt);

	ret = net_app_send_pkt(ctx, reply_pkt, &dst_addr, dst_len, K_NO_WAIT,
			       UINT_TO_POINTER(pkt_len));
	if (ret < 0) {
		NET_ERR("Cannot send data to peer (%d)", ret);
		net_pkt_unref(reply_pkt);

		tp_stats.pkt.dropped++;
	} else {
		tp_stats.pkt.sent++;
	}
#endif

	/* Print statistics only periodically */
	if (count > STATS_CHECK) {
		print_statistics();
		count = 0;
	}

	count++;
}

void start_udp(void)
{
	int ret;

	ret = net_app_init_udp_server(&udp, NULL, MY_PORT, NULL);
	if (ret < 0) {
		NET_ERR("Cannot init UDP service at port %d", MY_PORT);
		return;
	}

#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
	net_app_set_net_pkt_pool(&udp, tx_udp_slab, data_udp_pool);
#endif

	ret = net_app_set_cb(&udp, NULL, udp_received, pkt_sent, NULL);
	if (ret < 0) {
		NET_ERR("Cannot set callbacks (%d)", ret);
		net_app_release(&udp);
		return;
	}

	net_app_server_enable(&udp);

	ret = net_app_listen(&udp);
	if (ret < 0) {
		NET_ERR("Cannot wait connection (%d)", ret);
		net_app_release(&udp);
		return;
	}
}

void stop_udp(void)
{
	net_app_close(&udp);
	net_app_release(&udp);
}
