// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (C) 2023 The Android Open Source Project
 */

#include <fastboot.h>
#include <net.h>
#include <net/fastboot_tcp.h>
#include <net/tcp.h>

static char command[FASTBOOT_COMMAND_LEN] = {0};
static char response[FASTBOOT_RESPONSE_LEN] = {0};

static const unsigned short handshake_length = 4;
static const uchar *handshake = "FB01";

static u16 curr_sport;
static u16 curr_dport;
static u32 curr_tcp_seq_num;
static u32 curr_tcp_ack_num;
static unsigned int curr_request_len;
static enum fastboot_tcp_state {
	FASTBOOT_CLOSED,
	FASTBOOT_CONNECTED,
	FASTBOOT_DISCONNECTING
} state = FASTBOOT_CLOSED;

static void fastboot_tcp_answer(u8 action, unsigned int len)
{
	const u32 response_seq_num = curr_tcp_ack_num;
	const u32 response_ack_num = curr_tcp_seq_num +
		  (curr_request_len > 0 ? curr_request_len : 1);

	net_send_tcp_packet(len, htons(curr_sport), htons(curr_dport),
			    action, response_seq_num, response_ack_num);
}

static void fastboot_tcp_reset(void)
{
	fastboot_tcp_answer(TCP_RST, 0);
	state = FASTBOOT_CLOSED;
}

static void fastboot_tcp_send_packet(u8 action, const uchar *data, unsigned int len)
{
	uchar *pkt = net_get_async_tx_pkt_buf();

	memset(pkt, '\0', PKTSIZE);
	pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2;
	memcpy(pkt, data, len);
	fastboot_tcp_answer(action, len);
	memset(pkt, '\0', PKTSIZE);
}

static void fastboot_tcp_send_message(const char *message, unsigned int len)
{
	__be64 len_be = __cpu_to_be64(len);
	uchar *pkt = net_get_async_tx_pkt_buf();

	memset(pkt, '\0', PKTSIZE);
	pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2;
	// Put first 8 bytes as a big endian message length
	memcpy(pkt, &len_be, 8);
	pkt += 8;
	memcpy(pkt, message, len);
	fastboot_tcp_answer(TCP_ACK | TCP_PUSH, len + 8);
	memset(pkt, '\0', PKTSIZE);
}

static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport,
				      struct in_addr sip, u16 sport,
				      u32 tcp_seq_num, u32 tcp_ack_num,
				      u8 action, unsigned int len)
{
	int fastboot_command_id;
	u64 command_size;
	u8 tcp_fin = action & TCP_FIN;
	u8 tcp_push = action & TCP_PUSH;

	curr_sport = sport;
	curr_dport = dport;
	curr_tcp_seq_num = tcp_seq_num;
	curr_tcp_ack_num = tcp_ack_num;
	curr_request_len = len;

	switch (state) {
	case FASTBOOT_CLOSED:
		if (tcp_push) {
			if (len != handshake_length ||
			    strlen(pkt) != handshake_length ||
			    memcmp(pkt, handshake, handshake_length) != 0) {
				fastboot_tcp_reset();
				break;
			}
			fastboot_tcp_send_packet(TCP_ACK | TCP_PUSH,
						 handshake, handshake_length);
			state = FASTBOOT_CONNECTED;
		}
		break;
	case FASTBOOT_CONNECTED:
		if (tcp_fin) {
			fastboot_tcp_answer(TCP_FIN | TCP_ACK, 0);
			state = FASTBOOT_DISCONNECTING;
			break;
		}
		if (tcp_push) {
			// First 8 bytes is big endian message length
			command_size = __be64_to_cpu(*(u64 *)pkt);
			len -= 8;
			pkt += 8;

			// Only single packet messages are supported ATM
			if (strlen(pkt) != command_size) {
				fastboot_tcp_reset();
				break;
			}
			strlcpy(command, pkt, len + 1);
			fastboot_command_id = fastboot_handle_command(command, response);
			fastboot_tcp_send_message(response, strlen(response));
			fastboot_handle_boot(fastboot_command_id,
					     strncmp("OKAY", response, 4) == 0);
		}
		break;
	case FASTBOOT_DISCONNECTING:
		if (tcp_push)
			state = FASTBOOT_CLOSED;
		break;
	}

	memset(command, 0, FASTBOOT_COMMAND_LEN);
	memset(response, 0, FASTBOOT_RESPONSE_LEN);
	curr_sport = 0;
	curr_dport = 0;
	curr_tcp_seq_num = 0;
	curr_tcp_ack_num = 0;
	curr_request_len = 0;
}

void fastboot_tcp_start_server(void)
{
	printf("Using %s device\n", eth_get_name());
	printf("Listening for fastboot command on tcp %pI4\n", &net_ip);

	tcp_set_tcp_handler(fastboot_tcp_handler_ipv4);
}
