#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>

#include <sys/ioctl.h>

#include <linux/sockios.h>
#include <linux/ax25.h>

#include "config.h"

#define	TRUE		1
#define	FALSE		0

struct speed_struct {
	int     user_speed;
	speed_t termios_speed;
} speed_table[] = {
	{300,		B300},
	{600,		B600},
	{1200,		B1200},
	{2400,		B2400},
	{4800,		B4800},
	{9600,		B9600},
	{19200,		B19200},
	{38400,		B38400},
	{-1,		B0}
};


int setspeed(int fd, int speed)
{
	struct termios term;
	struct speed_struct *s;
	
	for (s = speed_table; s->user_speed != -1; s++)
		if (s->user_speed == speed)
			break;

	if (s->user_speed == -1) {
		fprintf(stderr, "axattach: invalid speed %d\n", speed);
		return(FALSE);
	}
	
	if (tcgetattr(fd, &term) == -1) {
		perror("tcgetattr");
		return(FALSE);
	}
	
	cfsetispeed(&term, s->termios_speed);
	cfsetospeed(&term, s->termios_speed);
	
	if (tcsetattr(fd, TCSANOW, &term) == -1) {
		perror("tcsetattr");
		return(FALSE);
	}
	
	return(TRUE);
}


int setifcall(int fd, char *name)
{
	char call[7];

	if (convert_call_entry(name, call) == -1)
		return(FALSE);
	
	if (ioctl(fd, SIOCSIFHWADDR, call) != 0) {
		close(fd);
		perror("SIOCSIFHWADDR");
		return(FALSE);
	}

	return(TRUE);
}
	

int main(int argc, char *argv[])
{
	int  fd;
	int  disc = N_SLIP;
	char buf[64];
	int  v = 4;
	int  speed = 0;

	while ((fd = getopt(argc, argv, "s:")) != -1) {
		switch (fd) {
			case 's':
				speed = atoi(optarg);
				break;
			case ':':
			case '?':
				fprintf(stderr, "usage: axattach [-s speed] <ttyinterface> <callsign>\n");
				return 1;
		}
	}
	
	if ((argc - optind) != 2) {
		fprintf(stderr, "usage: axattach [-s <speed>] <ttyinterface> <callsign>\n");
		return 1;
	}
	
	if ((fd = open(argv[optind], O_RDONLY | O_NDELAY)) == -1) {
		perror(argv[optind]);
		return 1;
	}

	if (speed != 0 && !setspeed(fd, speed))
		return 1;
	
	if (ioctl(fd, TIOCSETD, &disc) == -1) {
		perror("TIOCSETD");
		return 1;
	}
	
	if (ioctl(fd, SIOCGIFNAME, buf) == -1) {
		perror("SIOCGIFNAME");
		return 1;
	}
	
	if (!setifcall(fd, argv[optind + 1]))
		return 1;
	
	/* Now set the encapsulation */
	if (ioctl(fd, SIOCSIFENCAP, &v) == -1) {
		perror("SIOCSIFENCAP");
		return 1;
	}
		
	printf("Interface %s bound to tty %s with callsign %s\n",
		buf, argv[optind], argv[optind + 1]);	
		
	signal(SIGHUP, SIG_IGN);
	
	while (1)
		sleep(10000);
		
	/* NOT REACHED */
	return(0);
}
