/* vi: set sw=4 ts=4: */
/*
 * Copyright:     Copyright (C) 2001, Hewlett-Packard Company
 * Author:        Christopher Hoover <ch@hpl.hp.com>
 * Description:   xmodem functionality for uploading of kernels
 *                and the like
 * Created at:    Thu Dec 20 01:58:08 PST 2001
 *
 * xmodem functionality for uploading of kernels and the like
 *
 * Copyright (C) 2001 Hewlett-Packard Laboratories
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * This was originally written for blob and then adapted for busybox.
 */

#include "libbb.h"

#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define BS  0x08
#define PAD 0x1A

/*
Cf:
  http://www.textfiles.com/apple/xmodem
  http://www.phys.washington.edu/~belonis/xmodem/docxmodem.txt
  http://www.phys.washington.edu/~belonis/xmodem/docymodem.txt
  http://www.phys.washington.edu/~belonis/xmodem/modmprot.col
*/

#define TIMEOUT 1
#define TIMEOUT_LONG 10
#define MAXERRORS 10

#define read_fd  STDIN_FILENO
#define write_fd STDOUT_FILENO

static int read_byte(unsigned timeout)
{
	unsigned char buf;
	int n;

	alarm(timeout);
	/* NOT safe_read! We want ALRM to interrupt us */
	n = read(read_fd, &buf, 1);
	alarm(0);
	if (n == 1)
		return buf;
	return -1;
}

static int receive(/*int read_fd, */int file_fd)
{
	unsigned char blockBuf[1024];
	unsigned blockLength = 0;
	unsigned errors = 0;
	unsigned wantBlockNo = 1;
	unsigned length = 0;
	int do_crc = 1;
	char reply_char;
	unsigned timeout = TIMEOUT_LONG;

	/* Flush pending input */
	tcflush(read_fd, TCIFLUSH);

	/* Ask for CRC; if we get errors, we will go with checksum */
	reply_char = 'C';
	full_write(write_fd, &reply_char, 1);

	for (;;) {
		int blockBegin;
		int blockNo, blockNoOnesCompl;
		int cksum_or_crc;
		int expected;
		int i, j;

		blockBegin = read_byte(timeout);
		if (blockBegin < 0)
			goto timeout;

		/* If last block, remove padding */
		if (blockBegin == EOT) {
			/* Data blocks can be padded with ^Z characters */
			/* This code tries to detect and remove them */
			if (blockLength >= 3
			 && blockBuf[blockLength - 1] == PAD
			 && blockBuf[blockLength - 2] == PAD
			 && blockBuf[blockLength - 3] == PAD
			) {
				while (blockLength
			           && blockBuf[blockLength - 1] == PAD
				) {
					blockLength--;
				}
			}
		}
		/* Write previously received block */
		if (blockLength) {
			errno = 0;
			if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
				bb_perror_msg("can't write to file");
				goto fatal;
			}
		}

		timeout = TIMEOUT;
		reply_char = NAK;

		switch (blockBegin) {
		case SOH:
		case STX:
			break;
		case EOT:
			reply_char = ACK;
			full_write(write_fd, &reply_char, 1);
			return length;
		default:
			goto error;
		}

		/* Block no */
		blockNo = read_byte(TIMEOUT);
		if (blockNo < 0)
			goto timeout;

		/* Block no, in one's complement form */
		blockNoOnesCompl = read_byte(TIMEOUT);
		if (blockNoOnesCompl < 0)
			goto timeout;

		if (blockNo != (255 - blockNoOnesCompl)) {
			bb_error_msg("bad block ones compl");
			goto error;
		}

		blockLength = (blockBegin == SOH) ? 128 : 1024;

		for (i = 0; i < blockLength; i++) {
			int cc = read_byte(TIMEOUT);
			if (cc < 0)
				goto timeout;
			blockBuf[i] = cc;
		}

		if (do_crc) {
			cksum_or_crc = read_byte(TIMEOUT);
			if (cksum_or_crc < 0)
				goto timeout;
			cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT);
			if (cksum_or_crc < 0)
				goto timeout;
		} else {
			cksum_or_crc = read_byte(TIMEOUT);
			if (cksum_or_crc < 0)
				goto timeout;
		}

		if (blockNo == ((wantBlockNo - 1) & 0xff)) {
			/* a repeat of the last block is ok, just ignore it. */
			/* this also ignores the initial block 0 which is */
			/* meta data. */
			goto next;
		}
		if (blockNo != (wantBlockNo & 0xff)) {
			bb_error_msg("unexpected block no, 0x%08x, expecting 0x%08x", blockNo, wantBlockNo);
			goto error;
		}

		expected = 0;
		if (do_crc) {
			for (i = 0; i < blockLength; i++) {
				expected = expected ^ blockBuf[i] << 8;
				for (j = 0; j < 8; j++) {
					if (expected & 0x8000)
						expected = (expected << 1) ^ 0x1021;
					else
						expected = (expected << 1);
				}
			}
			expected &= 0xffff;
		} else {
			for (i = 0; i < blockLength; i++)
				expected += blockBuf[i];
			expected &= 0xff;
		}
		if (cksum_or_crc != expected) {
			bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x"
			                   : "checksum error, expected 0x%02x, got 0x%02x",
					expected, cksum_or_crc);
			goto error;
		}

		wantBlockNo++;
		length += blockLength;
 next:
		errors = 0;
		reply_char = ACK;
		full_write(write_fd, &reply_char, 1);
		continue;
 error:
 timeout:
		errors++;
		if (errors == MAXERRORS) {
			/* Abort */

			/* If were asking for crc, try again w/o crc */
			if (reply_char == 'C') {
				reply_char = NAK;
				errors = 0;
				do_crc = 0;
				goto timeout;
			}
			bb_error_msg("too many errors; giving up");
 fatal:
			/* 5 CAN followed by 5 BS. Don't try too hard... */
			safe_write(write_fd, "\030\030\030\030\030\010\010\010\010\010", 10);
			return -1;
		}

		/* Flush pending input */
		tcflush(read_fd, TCIFLUSH);

		full_write(write_fd, &reply_char, 1);
	} /* for (;;) */
}

static void sigalrm_handler(int UNUSED_PARAM signum)
{
}

int rx_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int rx_main(int argc UNUSED_PARAM, char **argv)
{
	struct termios tty, orig_tty;
	int termios_err;
	int file_fd;
	int n;

	/* Disabled by vda:
	 * why we can't receive from stdin? Why we *require*
	 * controlling tty?? */
	/*read_fd = xopen(CURRENT_TTY, O_RDWR);*/
	file_fd = xopen(single_argv(argv), O_RDWR|O_CREAT|O_TRUNC);

	termios_err = tcgetattr(read_fd, &tty);
	if (termios_err == 0) {
		orig_tty = tty;
		cfmakeraw(&tty);
		tcsetattr(read_fd, TCSAFLUSH, &tty);
	}

	/* No SA_RESTART: we want ALRM to interrupt read() */
	signal_no_SA_RESTART_empty_mask(SIGALRM, sigalrm_handler);

	n = receive(file_fd);

	if (termios_err == 0)
		tcsetattr(read_fd, TCSAFLUSH, &orig_tty);
	if (ENABLE_FEATURE_CLEAN_UP)
		close(file_fd);
	fflush_stdout_and_exit(n >= 0);
}
