/*
 *  serial_unix.cpp - Serial device driver, Unix specific stuff
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "sysdeps.h"

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
#include <termios.h>
#include <errno.h>
#ifdef __linux__
#include <linux/lp.h>
#include <linux/major.h>
#include <linux/kdev_t.h>
#endif

#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "prefs.h"
#include "serial.h"
#include "serial_defs.h"

extern "C" {
#include "sshpty.h"
}


#define DEBUG 0
#include "debug.h"

#define MONITOR 0


// IRIX missing or unsupported defines
#ifdef sgi
#ifndef CRTSCTS
#define CRTSCTS CNEW_RTSCTS
#endif
#ifndef B230400
#define B230400 B115200
#endif
#endif


// Missing functions
#ifndef HAVE_CFMAKERAW
static int cfmakeraw(struct termios *termios_p)
{
	termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
	termios_p->c_oflag &= ~OPOST;
	termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
	termios_p->c_cflag &= ~(CSIZE|PARENB);
	termios_p->c_cflag |= CS8;
	return 0;
}
#endif


// Driver private variables
class XSERDPort : public SERDPort {
public:
	XSERDPort(const char *dev)
	{
		device_name = dev;
		protocol = serial;
		fd = -1;
		pid = 0;
		input_thread_active = output_thread_active = false;

		Set_pthread_attr(&thread_attr, 2);
	}

	virtual ~XSERDPort()
	{
		if (input_thread_active) {
			input_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
			pthread_cancel(input_thread);
#endif
			pthread_join(input_thread, NULL);
			sem_destroy(&input_signal);
			input_thread_active = false;
		}
		if (output_thread_active) {
			output_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
			pthread_cancel(output_thread);
#endif
			pthread_join(output_thread, NULL);
			sem_destroy(&output_signal);
			output_thread_active = false;
		}
	}

	virtual int16 open(uint16 config);
	virtual int16 prime_in(uint32 pb, uint32 dce);
	virtual int16 prime_out(uint32 pb, uint32 dce);
	virtual int16 control(uint32 pb, uint32 dce, uint16 code);
	virtual int16 status(uint32 pb, uint32 dce, uint16 code);
	virtual int16 close(void);

private:
	bool open_pty(void);
	bool configure(uint16 config);
	void set_handshake(uint32 s, bool with_dtr);
	static void *input_func(void *arg);
	static void *output_func(void *arg);

	const char *device_name;			// Device name
	enum {serial, parallel, pty, midi}
		protocol;						// Type of device
	int fd;								// FD of device
	pid_t pid;							// PID of child process

	bool io_killed;						// Flag: KillIO called, I/O threads must not call deferred tasks
	bool quitting;						// Flag: Quit threads

	pthread_attr_t thread_attr;			// Input/output thread attributes

	bool input_thread_active;			// Flag: Input thread installed
	volatile bool input_thread_cancel;	// Flag: Cancel input thread
	pthread_t input_thread;				// Data input thread
	sem_t input_signal;					// Signal for input thread: execute command
	uint32 input_pb;					// Command parameter for input thread

	bool output_thread_active;			// Flag: Output thread installed
	volatile bool output_thread_cancel;	// Flag: Cancel output thread
	pthread_t output_thread;			// Data output thread
	sem_t output_signal;				// Signal for output thread: execute command
	uint32 output_pb;					// Command parameter for output thread

	struct termios mode;				// Terminal configuration
};


/*
 *  Initialization
 */

void SerialInit(void)
{
	// Read serial preferences and create structs for both ports
	the_serd_port[0] = new XSERDPort(PrefsFindString("seriala"));
	the_serd_port[1] = new XSERDPort(PrefsFindString("serialb"));
}


/*
 *  Deinitialization
 */

void SerialExit(void)
{
	delete (XSERDPort *)the_serd_port[0];
	delete (XSERDPort *)the_serd_port[1];
}


/*
 *  Open serial port
 */

int16 XSERDPort::open(uint16 config)
{
	// Don't open NULL name devices
	if (device_name == NULL)
		return openErr;

	// Init variables
	io_killed = false;
	quitting = false;

	// Open port, according to the syntax of the path
	if (device_name[0] == '|') {
		// Open a process via ptys
		if (!open_pty())
			goto open_error;
	}
	else if (!strcmp(device_name, "midi")) {
		// MIDI:  not yet implemented
		return openErr;
	}
	else {
		// Device special file
		fd = ::open(device_name, O_RDWR);
		if (fd < 0)
			goto open_error;

#if defined(__linux__)
		// Parallel port?
		struct stat st;
		if (fstat(fd, &st) == 0)
			if (S_ISCHR(st.st_mode))
				protocol = ((MAJOR(st.st_rdev) == LP_MAJOR) ? parallel : serial);
#elif defined(__FreeBSD__) || defined(__NetBSD__)
		// Parallel port?
		struct stat st;
		if (fstat(fd, &st) == 0)
			if (S_ISCHR(st.st_mode))
				protocol = (((st.st_rdev >> 16) == 16) ? parallel : serial);
#endif
	}

	// Configure port for raw mode
	if (protocol == serial || protocol == pty) {
		if (tcgetattr(fd, &mode) < 0)
			goto open_error;
		cfmakeraw(&mode);
		mode.c_cflag |= HUPCL;
		mode.c_cc[VMIN] = 1;
		mode.c_cc[VTIME] = 0;
		tcsetattr(fd, TCSAFLUSH, &mode);
	}
	configure(config);

	// Start input/output threads
	input_thread_cancel = false;
	output_thread_cancel = false;
	if (sem_init(&input_signal, 0, 0) < 0)
		goto open_error;
	if (sem_init(&output_signal, 0, 0) < 0)
		goto open_error; 
	input_thread_active = (pthread_create(&input_thread, &thread_attr, input_func, this) == 0);
	output_thread_active = (pthread_create(&output_thread, &thread_attr, output_func, this) == 0);
	if (!input_thread_active || !output_thread_active)
		goto open_error;
	return noErr;

open_error:
	if (input_thread_active) {
		input_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
		pthread_cancel(input_thread);
#endif
		pthread_join(input_thread, NULL);
		sem_destroy(&input_signal);
		input_thread_active = false;
	}
	if (output_thread_active) {
		output_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
		pthread_cancel(output_thread);
#endif
		pthread_join(output_thread, NULL);
		sem_destroy(&output_signal);
		output_thread_active = false;
	}
	if (fd > 0) {
		::close(fd);
		fd = -1;
	}
	return openErr;
}


/*
 *  Read data from port
 */

int16 XSERDPort::prime_in(uint32 pb, uint32 dce)
{
	// Send input command to input_thread
	read_done = false;
	read_pending = true;
	input_pb = pb;
	WriteMacInt32(input_dt + serdtDCE, dce);
	sem_post(&input_signal);
	return 1;	// Command in progress
}


/*
 *  Write data to port
 */

int16 XSERDPort::prime_out(uint32 pb, uint32 dce)
{
	// Send output command to output_thread
	write_done = false;
	write_pending = true;
	output_pb = pb;
	WriteMacInt32(output_dt + serdtDCE, dce);
	sem_post(&output_signal);
	return 1;	// Command in progress
}


/*
 *	Control calls
 */

int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
{
	switch (code) {
		case 1:			// KillIO
			io_killed = true;
			if (protocol == serial)
				tcflush(fd, TCIOFLUSH);
			while (read_pending || write_pending)
				usleep(10000);
			io_killed = false;
			return noErr;

		case kSERDConfiguration:
			if (configure(ReadMacInt16(pb + csParam)))
				return noErr;
			else
				return paramErr;

		case kSERDInputBuffer:
			return noErr;	// Not supported under Unix

		case kSERDSerHShake:
			set_handshake(pb + csParam, false);
			return noErr;

		case kSERDSetBreak:
			if (protocol == serial)
				tcsendbreak(fd, 0);
			return noErr;

		case kSERDClearBreak:
			return noErr;

		case kSERDBaudRate: {
			if (protocol != serial)
				return noErr;
			uint16 rate = ReadMacInt16(pb + csParam);
			speed_t baud_rate;
			if (rate <= 50) {
				rate = 50; baud_rate = B50;
			} else if (rate <= 75) {
				rate = 75; baud_rate = B75;
			} else if (rate <= 110) {
				rate = 110; baud_rate = B110;
			} else if (rate <= 134) {
				rate = 134; baud_rate = B134;
			} else if (rate <= 150) {
				rate = 150; baud_rate = B150;
			} else if (rate <= 200) {
				rate = 200; baud_rate = B200;
			} else if (rate <= 300) {
				rate = 300; baud_rate = B300;
			} else if (rate <= 600) {
				rate = 600; baud_rate = B600;
			} else if (rate <= 1200) {
				rate = 1200; baud_rate = B1200;
			} else if (rate <= 1800) {
				rate = 1800; baud_rate = B1800;
			} else if (rate <= 2400) {
				rate = 2400; baud_rate = B2400;
			} else if (rate <= 4800) {
				rate = 4800; baud_rate = B4800;
			} else if (rate <= 9600) {
				rate = 9600; baud_rate = B9600;
			} else if (rate <= 19200) {
				rate = 19200; baud_rate = B19200;
			} else if (rate <= 38400) {
				rate = 38400; baud_rate = B38400;
			} else if (rate <= 57600) {
				rate = 57600; baud_rate = B57600;
			} else {
				// Just for safety in case someone wants a rate between 57600 and 65535
				rate = 57600; baud_rate = B57600;
			}
			WriteMacInt16(pb + csParam, rate);
			cfsetispeed(&mode, baud_rate);
			cfsetospeed(&mode, baud_rate);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;
		}

		case kSERDHandshake:
		case kSERDHandshakeRS232:
			set_handshake(pb + csParam, true);
			return noErr;

		case kSERDMiscOptions:
			if (protocol != serial)
				return noErr;
			if (ReadMacInt8(pb + csParam) & kOptionPreserveDTR)
				mode.c_cflag &= ~HUPCL;
			else
				mode.c_cflag |= HUPCL;
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		case kSERDAssertDTR: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_DTR;
			ioctl(fd, TIOCMBIS, &status);
			return noErr;
		}

		case kSERDNegateDTR: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_DTR;
			ioctl(fd, TIOCMBIC, &status);
			return noErr;
		}

		case kSERDSetPEChar:
		case kSERDSetPEAltChar:
			return noErr;	// Not supported under Unix

		case kSERDResetChannel:
			if (protocol == serial)
				tcflush(fd, TCIOFLUSH);
			return noErr;

		case kSERDAssertRTS: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_RTS;
			ioctl(fd, TIOCMBIS, &status);
			return noErr;
		}

		case kSERDNegateRTS: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_RTS;
			ioctl(fd, TIOCMBIC, &status);
			return noErr;
		}

		case kSERD115KBaud:
			if (protocol != serial)
				return noErr;
			cfsetispeed(&mode, B115200);
			cfsetospeed(&mode, B115200);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		case kSERD230KBaud:
		case kSERDSetHighSpeed:
			if (protocol != serial)
				return noErr;
			cfsetispeed(&mode, B230400);
			cfsetospeed(&mode, B230400);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		default:
			printf("WARNING: SerialControl(): unimplemented control code %d\n", code);
			return controlErr;
	}
}


/*
 *	Status calls
 */

int16 XSERDPort::status(uint32 pb, uint32 dce, uint16 code)
{
	switch (code) {
		case kSERDInputCount: {
			int num;
			ioctl(fd, FIONREAD, &num);
			WriteMacInt32(pb + csParam, num);
			return noErr;
		}

		case kSERDStatus: {
			uint32 p = pb + csParam;
			WriteMacInt8(p + staCumErrs, cum_errors);
			cum_errors = 0;
			WriteMacInt8(p + staXOffSent, 0);
			WriteMacInt8(p + staXOffHold, 0);
			WriteMacInt8(p + staRdPend, read_pending);
			WriteMacInt8(p + staWrPend, write_pending);
			if (protocol != serial) {
				WriteMacInt8(p + staCtsHold, 0);
				WriteMacInt8(p + staDsrHold, 0);
				WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent);
			} else {
				unsigned int status;
				ioctl(fd, TIOCMGET, &status);
				WriteMacInt8(p + staCtsHold, status & TIOCM_CTS ? 0 : 1);
				WriteMacInt8(p + staDsrHold, status & TIOCM_DTR ? 0 : 1);
				WriteMacInt8(p + staModemStatus,
					(status & TIOCM_DSR ? dsrEvent : 0)
					| (status & TIOCM_RI ? riEvent : 0)
					| (status & TIOCM_CD ? dcdEvent : 0)
					| (status & TIOCM_CTS ? ctsEvent : 0));
			}
			return noErr;
		}

		default:
			printf("WARNING: SerialStatus(): unimplemented status code %d\n", code);
			return statusErr;
	}
}


/*
 *	Close serial port
 */

int16 XSERDPort::close()
{
	// Kill threads
	if (input_thread_active) {
		quitting = true;
		sem_post(&input_signal);
		pthread_join(input_thread, NULL);
		input_thread_active = false;
		sem_destroy(&input_signal);
	}
	if (output_thread_active) {
		quitting = true;
		sem_post(&output_signal);
		pthread_join(output_thread, NULL);
		output_thread_active = false;
		sem_destroy(&output_signal);
	}

	// Close port
	if (fd > 0)
		::close(fd);
	fd = -1;

	// Wait for the subprocess to exit
	if (pid)
		waitpid(pid, NULL, 0);
	pid = 0;

	return noErr;
}


/*
 * Open a process via ptys
 */

bool XSERDPort::open_pty(void)
{
	// Talk to a process via a pty
	char slave[128];
	int slavefd;

	protocol = pty;
	if (!pty_allocate(&fd, &slavefd, slave, sizeof(slave)))
		return false;
		
	fflush(stdout);
	fflush(stderr);
	switch (pid = fork()) {
	case -1:				// error
		return false;
		break;
	case 0:					// child
		::close(fd);

		/* Make the pseudo tty our controlling tty. */
		pty_make_controlling_tty(&slavefd, slave);

		::close(0); dup(slavefd); // Use the slave fd for stdin,
		::close(1); dup(slavefd); // stdout,
		::close(2); dup(slavefd); // and stderr.

		// <should we be more paranoid about closing unused fds?>
		// <should we drop privileges if running setuid?>

		// Let the shell do the dirty work
		execlp("/bin/sh", "/bin/sh", "-c", ++device_name, (char *)NULL);

		// exec failed!
		printf("serial_open:  could not exec %s: %s\n",
			   "/bin/sh", strerror(errno));
		exit(1);
		break;
	default:				// parent
		// Pid was stored above
		break;
	}

	return true;
}


/*
 *  Configure serial port with MacOS config word
 */

bool XSERDPort::configure(uint16 config)
{
	D(bug(" configure %04x\n", config));
	if (protocol != serial)
		return true;

	// Set number of stop bits
	switch (config & 0xc000) {
		case stop10:
			mode.c_cflag &= ~CSTOPB;
			break;
		case stop20:
			mode.c_cflag |= CSTOPB;
			break;
		default:
			return false;
	}

	// Set parity mode
	switch (config & 0x3000) {
		case noParity:
			mode.c_iflag &= ~INPCK;
			mode.c_oflag &= ~PARENB;
			break;
		case oddParity:
			mode.c_iflag |= INPCK;
			mode.c_oflag |= PARENB;
			mode.c_oflag |= PARODD;
			break;
		case evenParity:
			mode.c_iflag |= INPCK;
			mode.c_oflag |= PARENB;
			mode.c_oflag &= ~PARODD;
			break;
		default:
			return false;
	}

	// Set number of data bits
	switch (config & 0x0c00) {
		case data5:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS5;
			break;
		case data6:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS6;
			break;
		case data7:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS7;
			break;
		case data8:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS8;
			break;
	}

	// Set baud rate
	speed_t baud_rate;
	switch (config & 0x03ff) {
		case baud150: baud_rate = B150; break;
		case baud300: baud_rate = B300; break;
		case baud600: baud_rate = B600; break;
		case baud1200: baud_rate = B1200; break;
		case baud1800: baud_rate = B1800; break;
		case baud2400: baud_rate = B2400; break;
		case baud4800: baud_rate = B4800; break;
		case baud9600: baud_rate = B9600; break;
		case baud19200: baud_rate = B19200; break;
		case baud38400: baud_rate = B38400; break;
		case baud57600: baud_rate = B57600; break;
		default:
			return false;
	}
	cfsetispeed(&mode, baud_rate);
	cfsetospeed(&mode, baud_rate);
	tcsetattr(fd, TCSANOW, &mode);
	return true;
}


/*
 *  Set serial handshaking
 */

void XSERDPort::set_handshake(uint32 s, bool with_dtr)
{
	D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n",
		ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3),
		ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7)));
	if (protocol != serial)
		return;

	if (with_dtr) {
		if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR))
			mode.c_cflag |= CRTSCTS;
		else
			mode.c_cflag &= ~CRTSCTS;
	} else {
		if (ReadMacInt8(s + shkFCTS))
			mode.c_cflag |= CRTSCTS;
		else
			mode.c_cflag &= ~CRTSCTS;
	}

	D(bug(" %sware flow control\n", mode.c_cflag & CRTSCTS ? "hard" : "soft"));
	tcsetattr(fd, TCSANOW, &mode);
}


/*
 *  Data input thread
 */

void *XSERDPort::input_func(void *arg)
{
	XSERDPort *s = (XSERDPort *)arg;
	while (!s->input_thread_cancel) {

		// Wait for commands
		sem_wait(&s->input_signal);
		if (s->quitting)
			break;

		// Execute command
		void *buf = Mac2HostAddr(ReadMacInt32(s->input_pb + ioBuffer));
		uint32 length = ReadMacInt32(s->input_pb + ioReqCount);
		D(bug("input_func waiting for %ld bytes of data...\n", length));
		int32 actual = read(s->fd, buf, length);
		D(bug(" %ld bytes received\n", actual));

#if MONITOR
		bug("Receiving serial data:\n");
		uint8 *adr = (uint8 *)buf;
		for (int i=0; i<actual; i++) {
			bug("%02x ", adr[i]);
		}
		bug("\n");
#endif

		// KillIO called? Then simply return
		if (s->io_killed) {

			WriteMacInt16(s->input_pb + ioResult, uint16(abortErr));
			WriteMacInt32(s->input_pb + ioActCount, 0);
			s->read_pending = s->read_done = false;

		} else {

			// Set error code
			if (actual >= 0) {
				WriteMacInt32(s->input_pb + ioActCount, actual);
				WriteMacInt32(s->input_dt + serdtResult, noErr);
			} else {
				WriteMacInt32(s->input_pb + ioActCount, 0);
				WriteMacInt32(s->input_dt + serdtResult, uint16(readErr));
			}

			// Trigger serial interrupt
			D(bug(" triggering serial interrupt\n"));
			s->read_done = true;
			SetInterruptFlag(INTFLAG_SERIAL);
			TriggerInterrupt();
		}
	}
	return NULL;
}


/*
 *  Data output thread
 */

void *XSERDPort::output_func(void *arg)
{
	XSERDPort *s = (XSERDPort *)arg;
	while (!s->output_thread_cancel) {

		// Wait for commands
		sem_wait(&s->output_signal);
		if (s->quitting)
			break;

		// Execute command
		void *buf = Mac2HostAddr(ReadMacInt32(s->output_pb + ioBuffer));
		uint32 length = ReadMacInt32(s->output_pb + ioReqCount);
		D(bug("output_func transmitting %ld bytes of data...\n", length));

#if MONITOR
		bug("Sending serial data:\n");
		uint8 *adr = (uint8 *)buf;
		for (int i=0; i<length; i++) {
			bug("%02x ", adr[i]);
		}
		bug("\n");
#endif

		int32 actual = write(s->fd, buf, length);
		D(bug(" %ld bytes transmitted\n", actual));

		// KillIO called? Then simply return
		if (s->io_killed) {

			WriteMacInt16(s->output_pb + ioResult, uint16(abortErr));
			WriteMacInt32(s->output_pb + ioActCount, 0);
			s->write_pending = s->write_done = false;

		} else {

			// Set error code
			if (actual >= 0) {
				WriteMacInt32(s->output_pb + ioActCount, actual);
				WriteMacInt32(s->output_dt + serdtResult, noErr);
			} else {
				WriteMacInt32(s->output_pb + ioActCount, 0);
				WriteMacInt32(s->output_dt + serdtResult, uint16(writErr));
			}
	
			// Trigger serial interrupt
			D(bug(" triggering serial interrupt\n"));
			s->write_done = true;
			SetInterruptFlag(INTFLAG_SERIAL);
			TriggerInterrupt();
		}
	}
	return NULL;
}
