// unix_serial.c, Peter McGavin, 1 July 2002

// public domain

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>

#include "util.h"

int serial_fd = -1;
static struct termios oldserialtio;

/**********************************************************************/
void CloseSerial (void)
{
  debug ("In CloseSerial()\n");
  if (serial_fd >= 0) {
    tcflush (serial_fd, TCIFLUSH);
    tcsetattr (serial_fd, TCSANOW, &oldserialtio);
    close (serial_fd);
    serial_fd = -1;
  }
}

/**********************************************************************/
static void sighandler (int sig)
{
  CloseSerial ();
  debug ("In sighandler %d\n", sig);
  exit (EXIT_SUCCESS);
}

/**********************************************************************/
int OpenSerial (char *devname)
{
  struct termios newtio;

  if (serial_fd >= 0)  /* check if already open */
    return 0;

  if ((serial_fd = open (devname, O_RDWR | O_NOCTTY)) < 0) {
    serial_fd = -1;
    return 0;
  }

  if (!isatty (serial_fd)) {
    close (serial_fd);
    serial_fd = -1;
    return 0;
  }

  tcgetattr (serial_fd, &oldserialtio);

  signal (SIGINT, SIG_IGN);
  signal (SIGHUP, sighandler);
  atexit (CloseSerial);   /* restore port settings on exit */

  memset (&newtio, 0, sizeof(newtio));
  //  newtio.c_cflag = CRTSCTS | CS8 | CREAD;
  newtio.c_cflag = CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR;
  newtio.c_oflag = 0;
  newtio.c_lflag = 0;
  newtio.c_cc[VTIME] = 0;   /* inter-character timer unused */
  newtio.c_cc[VMIN] = 1;   /* blocking read until 1 char received */
  cfsetispeed (&newtio, B1200);
  cfsetospeed (&newtio, B1200);
  tcflush (serial_fd, TCIFLUSH);  /* flushes data received but not read */
  tcsetattr (serial_fd, TCSANOW, &newtio); /* set new port settings */

  return 1;
}

/**********************************************************************/
