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

#include <common.h>
#include <command.h>
#include <fastboot.h>
#include <net.h>
#include <net/fastboot_udp.h>

enum {
	FASTBOOT_ERROR = 0,
	FASTBOOT_QUERY = 1,
	FASTBOOT_INIT = 2,
	FASTBOOT_FASTBOOT = 3,
};

struct __packed fastboot_header {
	uchar id;
	uchar flags;
	unsigned short seq;
};

#define PACKET_SIZE 1024
#define DATA_SIZE (PACKET_SIZE - sizeof(struct fastboot_header))

/* Sequence number sent for every packet */
static unsigned short sequence_number = 1;
static const unsigned short packet_size = PACKET_SIZE;
static const unsigned short udp_version = 1;

/* Keep track of last packet for resubmission */
static uchar last_packet[PACKET_SIZE];
static unsigned int last_packet_len;

static struct in_addr fastboot_remote_ip;
/* The UDP port at their end */
static int fastboot_remote_port;
/* The UDP port at our end */
static int fastboot_our_port;

/**
 * fastboot_udp_send_info() - Send an INFO packet during long commands.
 *
 * @msg: String describing the reason for waiting
 */
static void fastboot_udp_send_info(const char *msg)
{
	uchar *packet;
	uchar *packet_base;
	int len = 0;
	char response[FASTBOOT_RESPONSE_LEN] = {0};

	struct fastboot_header response_header = {
		.id = FASTBOOT_FASTBOOT,
		.flags = 0,
		.seq = htons(sequence_number)
	};
	++sequence_number;
	packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
	packet_base = packet;

	/* Write headers */
	memcpy(packet, &response_header, sizeof(response_header));
	packet += sizeof(response_header);
	/* Write response */
	fastboot_response("INFO", response, "%s", msg);
	memcpy(packet, response, strlen(response));
	packet += strlen(response);

	len = packet - packet_base;

	/* Save packet for retransmitting */
	last_packet_len = len;
	memcpy(last_packet, packet_base, last_packet_len);

	net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
			    fastboot_remote_port, fastboot_our_port, len);
}

/**
 * fastboot_timed_send_info() - Send INFO packet every 30 seconds
 *
 * @msg: String describing the reason for waiting
 *
 * Send an INFO packet during long commands based on timer. An INFO packet
 * is sent if the time is 30 seconds after start. Else, noop.
 */
static void fastboot_timed_send_info(const char *msg)
{
	static ulong start;

	/* Initialize timer */
	if (start == 0)
		start = get_timer(0);
	ulong time = get_timer(start);
	/* Send INFO packet to host every 30 seconds */
	if (time >= 30000) {
		start = get_timer(0);
		fastboot_udp_send_info(msg);
	}
}

/**
 * fastboot_send() - Sends a packet in response to received fastboot packet
 *
 * @header: Header for response packet
 * @fastboot_data: Pointer to received fastboot data
 * @fastboot_data_len: Length of received fastboot data
 * @retransmit: Nonzero if sending last sent packet
 */
static void fastboot_send(struct fastboot_header header, char *fastboot_data,
			  unsigned int fastboot_data_len, uchar retransmit)
{
	uchar *packet;
	uchar *packet_base;
	int len = 0;
	const char *error_msg = "An error occurred.";
	short tmp;
	struct fastboot_header response_header = header;
	static char command[FASTBOOT_COMMAND_LEN];
	static int cmd = -1;
	static bool pending_command;
	char response[FASTBOOT_RESPONSE_LEN] = {0};

	/*
	 * We will always be sending some sort of packet, so
	 * cobble together the packet headers now.
	 */
	packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
	packet_base = packet;

	/* Resend last packet */
	if (retransmit) {
		memcpy(packet, last_packet, last_packet_len);
		net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
				    fastboot_remote_port, fastboot_our_port,
				    last_packet_len);
		return;
	}

	response_header.seq = htons(response_header.seq);
	memcpy(packet, &response_header, sizeof(response_header));
	packet += sizeof(response_header);

	switch (header.id) {
	case FASTBOOT_QUERY:
		tmp = htons(sequence_number);
		memcpy(packet, &tmp, sizeof(tmp));
		packet += sizeof(tmp);
		break;
	case FASTBOOT_INIT:
		tmp = htons(udp_version);
		memcpy(packet, &tmp, sizeof(tmp));
		packet += sizeof(tmp);
		tmp = htons(packet_size);
		memcpy(packet, &tmp, sizeof(tmp));
		packet += sizeof(tmp);
		break;
	case FASTBOOT_ERROR:
		memcpy(packet, error_msg, strlen(error_msg));
		packet += strlen(error_msg);
		break;
	case FASTBOOT_FASTBOOT:
		if (cmd == FASTBOOT_COMMAND_DOWNLOAD) {
			if (!fastboot_data_len && !fastboot_data_remaining()) {
				fastboot_data_complete(response);
			} else {
				fastboot_data_download(fastboot_data,
						       fastboot_data_len,
						       response);
			}
		} else if (!pending_command) {
			strlcpy(command, fastboot_data,
				min((size_t)fastboot_data_len + 1,
				    sizeof(command)));
			pending_command = true;
		} else {
			cmd = fastboot_handle_command(command, response);
			pending_command = false;
		}
		/*
		 * Sent some INFO packets, need to update sequence number in
		 * header
		 */
		if (header.seq != sequence_number) {
			response_header.seq = htons(sequence_number);
			memcpy(packet_base, &response_header,
			       sizeof(response_header));
		}
		/* Write response to packet */
		memcpy(packet, response, strlen(response));
		packet += strlen(response);
		break;
	default:
		pr_err("ID %d not implemented.\n", header.id);
		return;
	}

	len = packet - packet_base;

	/* Save packet for retransmitting */
	last_packet_len = len;
	memcpy(last_packet, packet_base, last_packet_len);

	net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
			    fastboot_remote_port, fastboot_our_port, len);

	fastboot_handle_boot(cmd, strncmp("OKAY", response, 4) == 0);

	if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4))
		cmd = -1;
}

/**
 * fastboot_handler() - Incoming UDP packet handler.
 *
 * @packet: Pointer to incoming UDP packet
 * @dport: Destination UDP port
 * @sip: Source IP address
 * @sport: Source UDP port
 * @len: Packet length
 */
static void fastboot_handler(uchar *packet, unsigned int dport,
			     struct in_addr sip, unsigned int sport,
			     unsigned int len)
{
	struct fastboot_header header;
	char fastboot_data[DATA_SIZE] = {0};
	unsigned int fastboot_data_len = 0;

	if (dport != fastboot_our_port)
		return;

	fastboot_remote_ip = sip;
	fastboot_remote_port = sport;

	if (len < sizeof(struct fastboot_header) || len > PACKET_SIZE)
		return;
	memcpy(&header, packet, sizeof(header));
	header.flags = 0;
	header.seq = ntohs(header.seq);
	packet += sizeof(header);
	len -= sizeof(header);

	switch (header.id) {
	case FASTBOOT_QUERY:
		fastboot_send(header, fastboot_data, 0, 0);
		break;
	case FASTBOOT_INIT:
	case FASTBOOT_FASTBOOT:
		fastboot_data_len = len;
		if (len > 0)
			memcpy(fastboot_data, packet, len);
		if (header.seq == sequence_number) {
			fastboot_send(header, fastboot_data,
				      fastboot_data_len, 0);
			sequence_number++;
		} else if (header.seq == sequence_number - 1) {
			/* Retransmit last sent packet */
			fastboot_send(header, fastboot_data,
				      fastboot_data_len, 1);
		}
		break;
	default:
		pr_err("ID %d not implemented.\n", header.id);
		header.id = FASTBOOT_ERROR;
		fastboot_send(header, fastboot_data, 0, 0);
		break;
	}
}

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

	fastboot_our_port = CONFIG_UDP_FUNCTION_FASTBOOT_PORT;

	if (IS_ENABLED(CONFIG_FASTBOOT_FLASH))
		fastboot_set_progress_callback(fastboot_timed_send_info);

	net_set_udp_handler(fastboot_handler);

	/* zero out server ether in case the server ip has changed */
	memset(net_server_ethaddr, 0, 6);
}
