/*
 * Copyright (c) 2015 Intel Corporation
 * Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL);

#include <zephyr/kernel.h>

#include <zephyr/net/net_pkt.h>
#include <zephyr/net/udp.h>

#include "zperf_session.h"

#define SESSION_MAX CONFIG_NET_ZPERF_MAX_SESSIONS

static struct session sessions[SESSION_PROTO_END][SESSION_MAX];

/* Get session from a given packet */
struct session *get_session(const struct sockaddr *addr,
			    enum session_proto proto)
{
	struct session *active = NULL;
	struct session *free = NULL;
	int i = 0;
	const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr;
	const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;

	if (proto != SESSION_TCP && proto != SESSION_UDP) {
		NET_ERR("Error! unsupported proto.\n");
		return NULL;
	}

	/* Check whether we already have an active session */
	while (!active && i < SESSION_MAX) {
		struct session *ptr = &sessions[proto][i];

		if (IS_ENABLED(CONFIG_NET_IPV4) &&
		    addr->sa_family == AF_INET &&
		    ptr->ip.family == AF_INET &&
		    ptr->port == addr4->sin_port &&
		    net_ipv4_addr_cmp(&ptr->ip.in_addr, &addr4->sin_addr)) {
			/* We found an active session */
			active = ptr;
			break;
		}

		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    addr->sa_family == AF_INET6 &&
		    ptr->ip.family == AF_INET6 &&
		    ptr->port == addr6->sin6_port &&
		    net_ipv6_addr_cmp(&ptr->ip.in6_addr, &addr6->sin6_addr)) {
			/* We found an active session */
			active = ptr;
			break;
		}

		if (!free && (ptr->state == STATE_NULL ||
			      ptr->state == STATE_COMPLETED)) {
			/* We found a free slot - just in case */
			free = ptr;
		}

		i++;
	}

	/* If no active session then create a new one */
	if (!active && free) {
		active = free;

		if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) {
			active->port = addr4->sin_port;
			active->ip.family = AF_INET;
			net_ipaddr_copy(&active->ip.in_addr, &addr4->sin_addr);
		} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
			   addr->sa_family == AF_INET6) {
			active->port = addr6->sin6_port;
			active->ip.family = AF_INET6;
			net_ipaddr_copy(&active->ip.in6_addr, &addr6->sin6_addr);
		}
	}

	return active;
}

void zperf_reset_session_stats(struct session *session)
{
	if (!session) {
		return;
	}

	session->counter = 0U;
	session->start_time = 0U;
	session->next_id = 1U;
	session->length = 0U;
	session->outorder = 0U;
	session->error = 0U;
	session->jitter = 0;
	session->last_transit_time = 0;
}

void zperf_session_init(void)
{
	int i, j;

	for (i = 0; i < SESSION_PROTO_END; i++) {
		for (j = 0; j < SESSION_MAX; j++) {
			sessions[i][j].state = STATE_NULL;
			zperf_reset_session_stats(&(sessions[i][j]));
		}
	}
}
