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

#include "tp.h"

#define is(_a, _b) (strcmp((_a), (_b)) == 0)

#ifndef MIN3
#define MIN3(_a, _b, _c) MIN((_a), MIN((_b), (_c)))
#endif

#define th_sport(_x) UNALIGNED_GET(&(_x)->th_sport)
#define th_dport(_x) UNALIGNED_GET(&(_x)->th_dport)
#define th_seq(_x) ntohl(UNALIGNED_GET(&(_x)->th_seq))
#define th_ack(_x) ntohl(UNALIGNED_GET(&(_x)->th_ack))
#define th_off(_x) ((_x)->th_off)
#define th_flags(_x) UNALIGNED_GET(&(_x)->th_flags)
#define th_win(_x) UNALIGNED_GET(&(_x)->th_win)

#define tcp_slist(_conn, _slist, _op, _type, _link)			\
({									\
	k_mutex_lock(&_conn->lock, K_FOREVER);				\
									\
	sys_snode_t *_node = sys_slist_##_op(_slist);			\
									\
	_type * _x = _node ? CONTAINER_OF(_node, _type, _link) : NULL;	\
									\
	k_mutex_unlock(&_conn->lock);					\
									\
	_x;								\
})

#if defined(CONFIG_NET_TEST_PROTOCOL)
#define tcp_malloc(_size) \
	tp_malloc(_size, tp_basename(__FILE__), __LINE__, __func__)
#define tcp_calloc(_nmemb, _size) \
	tp_calloc(_nmemb, _size, tp_basename(__FILE__), __LINE__, __func__)
#define tcp_free(_ptr) tp_free(_ptr, tp_basename(__FILE__), __LINE__, __func__)
#else
#define tcp_malloc(_size) k_malloc(_size)
#define tcp_calloc(_nmemb, _size) k_calloc(_nmemb, _size)
#define tcp_free(_ptr) k_free(_ptr)
#endif

#define TCP_PKT_ALLOC_TIMEOUT K_MSEC(CONFIG_NET_TCP_PKT_ALLOC_TIMEOUT)

#if defined(CONFIG_NET_TEST_PROTOCOL)
#define tcp_pkt_clone(_pkt) tp_pkt_clone(_pkt, tp_basename(__FILE__), __LINE__)
#define tcp_pkt_unref(_pkt) tp_pkt_unref(_pkt, tp_basename(__FILE__), __LINE__)
#else
#define tcp_pkt_clone(_pkt) net_pkt_clone(_pkt, TCP_PKT_ALLOC_TIMEOUT)
#define tcp_pkt_unref(_pkt) net_pkt_unref(_pkt)
#define tp_pkt_alloc(args...)
#endif

#define tcp_pkt_ref(_pkt) net_pkt_ref(_pkt)
#define tcp_pkt_alloc(_conn, _len)					\
({									\
	struct net_pkt *_pkt;						\
									\
	if ((_len) > 0) {						\
		_pkt = net_pkt_alloc_with_buffer(			\
			(_conn)->iface,					\
			(_len),						\
			net_context_get_family((_conn)->context),	\
			IPPROTO_TCP,					\
			TCP_PKT_ALLOC_TIMEOUT);				\
	} else {							\
		_pkt = net_pkt_alloc(TCP_PKT_ALLOC_TIMEOUT);		\
	}								\
									\
	tp_pkt_alloc(_pkt, tp_basename(__FILE__), __LINE__);		\
									\
	_pkt;								\
})

#define tcp_rx_pkt_alloc(_conn, _len)					\
({									\
	struct net_pkt *_pkt;						\
									\
	if ((_len) > 0) {						\
		_pkt = net_pkt_rx_alloc_with_buffer(			\
			(_conn)->iface,					\
			(_len),						\
			net_context_get_family((_conn)->context),	\
			IPPROTO_TCP,					\
			TCP_PKT_ALLOC_TIMEOUT);				\
	} else {							\
		_pkt = net_pkt_rx_alloc(TCP_PKT_ALLOC_TIMEOUT);		\
	}								\
									\
	tp_pkt_alloc(_pkt, tp_basename(__FILE__), __LINE__);		\
									\
	_pkt;								\
})


#if defined(CONFIG_NET_TEST_PROTOCOL)
#define conn_seq(_conn, _req) \
	tp_seq_track(TP_SEQ, &(_conn)->seq, (_req), tp_basename(__FILE__), \
			__LINE__, __func__)
#define conn_ack(_conn, _req) \
	tp_seq_track(TP_ACK, &(_conn)->ack, (_req), tp_basename(__FILE__), \
			__LINE__, __func__)
#else
#define conn_seq(_conn, _req) (_conn)->seq += (_req)
#define conn_ack(_conn, _req) (_conn)->ack += (_req)
#endif

#define NET_TCP_DEFAULT_MSS 536

#define conn_mss(_conn)							\
	MIN((_conn)->recv_options.mss_found ? (_conn)->recv_options.mss	\
					    : NET_TCP_DEFAULT_MSS,	\
	    net_tcp_get_supported_mss(_conn))

#define conn_state(_conn, _s)						\
({									\
	NET_DBG("%s->%s",						\
		tcp_state_to_str((_conn)->state, false),		\
		tcp_state_to_str((_s), false));				\
	(_conn)->state = _s;						\
})

#define conn_send_data_dump(_conn)                                             \
	({                                                                     \
		NET_DBG("conn: %p total=%zd, unacked_len=%d, "                 \
			"send_win=%hu, mss=%hu",                               \
			(_conn), net_pkt_get_len((_conn)->send_data),          \
			_conn->unacked_len, _conn->send_win,                   \
			(uint16_t)conn_mss((_conn)));                          \
		NET_DBG("conn: %p send_data_timer=%hu, send_data_retries=%hu", \
			(_conn),                                               \
			(bool)k_ticks_to_ms_ceil32(                            \
				k_work_delayable_remaining_get(                \
					&(_conn)->send_data_timer)),           \
			(_conn)->send_data_retries);                           \
	})

enum pkt_addr {
	TCP_EP_SRC = 1,
	TCP_EP_DST = 0
};

struct tcphdr {
	uint16_t th_sport;
	uint16_t th_dport;
	uint32_t th_seq;
	uint32_t th_ack;
#ifdef CONFIG_LITTLE_ENDIAN
	uint8_t th_x2:4;	/* unused */
	uint8_t th_off:4;	/* data offset, in units of 32-bit words */
#else
	uint8_t th_off:4;
	uint8_t th_x2:4;
#endif
	uint8_t th_flags;
	uint16_t th_win;
	uint16_t th_sum;
	uint16_t th_urp;
} __packed;

enum th_flags {
	FIN = BIT(0),
	SYN = BIT(1),
	RST = BIT(2),
	PSH = BIT(3),
	ACK = BIT(4),
	URG = BIT(5),
	ECN = BIT(6),
	CWR = BIT(7),
};

struct tcp_mss_option {
	uint32_t option;
};

enum tcp_state {
	TCP_LISTEN = 1,
	TCP_SYN_SENT,
	TCP_SYN_RECEIVED,
	TCP_ESTABLISHED,
	TCP_FIN_WAIT_1,
	TCP_FIN_WAIT_2,
	TCP_CLOSE_WAIT,
	TCP_CLOSING,
	TCP_LAST_ACK,
	TCP_TIME_WAIT,
	TCP_CLOSED
};

enum tcp_data_mode {
	TCP_DATA_MODE_SEND = 0,
	TCP_DATA_MODE_RESEND = 1
};

union tcp_endpoint {
	struct sockaddr sa;
	struct sockaddr_in sin;
	struct sockaddr_in6 sin6;
};

/* TCP Option codes */
#define NET_TCP_END_OPT          0
#define NET_TCP_NOP_OPT          1
#define NET_TCP_MSS_OPT          2
#define NET_TCP_WINDOW_SCALE_OPT 3

/* TCP Option sizes */
#define NET_TCP_END_SIZE          1
#define NET_TCP_NOP_SIZE          1
#define NET_TCP_MSS_SIZE          4
#define NET_TCP_WINDOW_SCALE_SIZE 3

struct tcp_options {
	uint16_t mss;
	uint16_t window;
	bool mss_found : 1;
	bool wnd_found : 1;
};

struct tcp { /* TCP connection */
	sys_snode_t next;
	struct net_context *context;
	struct net_pkt *send_data;
	struct net_pkt *queue_recv_data;
	struct net_if *iface;
	void *recv_user_data;
	sys_slist_t send_queue;
	union {
		net_tcp_accept_cb_t accept_cb;
		struct tcp *accepted_conn;
	};
	net_context_connect_cb_t connect_cb;
	struct k_mutex lock;
	struct k_sem connect_sem; /* semaphore for blocking connect */
	struct k_sem tx_sem; /* Semaphore indicating if transfers are blocked . */
	struct k_fifo recv_data;  /* temp queue before passing data to app */
	struct tcp_options recv_options;
	struct tcp_options send_options;
	struct k_work_delayable send_timer;
	struct k_work_delayable recv_queue_timer;
	struct k_work_delayable send_data_timer;
	struct k_work_delayable timewait_timer;
	struct k_work_delayable persist_timer;
	struct k_work_delayable ack_timer;

	union {
		/* Because FIN and establish timers are never happening
		 * at the same time, share the timer between them to
		 * save memory.
		 */
		struct k_work_delayable fin_timer;
		struct k_work_delayable establish_timer;
	};
	union tcp_endpoint src;
	union tcp_endpoint dst;
	size_t send_data_total;
	size_t send_retries;
	int unacked_len;
	atomic_t ref_count;
	enum tcp_state state;
	enum tcp_data_mode data_mode;
	uint32_t seq;
	uint32_t ack;
	uint16_t recv_win_max;
	uint16_t recv_win;
	uint16_t send_win_max;
	uint16_t send_win;
#ifdef CONFIG_NET_TCP_RANDOMIZED_RTO
	uint16_t rto;
#endif
	uint8_t send_data_retries;
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
	uint8_t dup_ack_cnt;
#endif
	uint8_t zwp_retries;
	bool in_retransmission : 1;
	bool in_connect : 1;
	bool in_close : 1;
	bool tcp_nodelay : 1;
};

#define _flags(_fl, _op, _mask, _cond)					\
({									\
	bool result = false;						\
									\
	if (UNALIGNED_GET(_fl) && (_cond) &&				\
	    (UNALIGNED_GET(_fl) _op(_mask))) {				\
		UNALIGNED_PUT(UNALIGNED_GET(_fl) & ~(_mask), _fl);	\
		result = true;						\
	}								\
									\
	result;								\
})

#define FL(_fl, _op, _mask, _args...)					\
	_flags(_fl, _op, _mask, strlen("" #_args) ? _args : true)

typedef void (*net_tcp_cb_t)(struct tcp *conn, void *user_data);
