#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

#define _POSIX_SOURCE 1 /* POSIX compliant source */

#define FALSE 0
#define TRUE 1

//volatile int STOP=FALSE; 

int main( int argc, char* argv[] )
{
  int fd;
  struct termios oldtio,newtio;
  char* device;
  speed_t speed;
  int ctrllines; 
  char* sendStr;
  int running, i;

  if (argc != 5) {
    fprintf(stderr, "Usage: sersend <dev> <baudrate> <char mask> <string>\n");
    fprintf(stderr, "Example: sersend /dev/ttyS1 B9600 8N1 123\n");
    exit(1);
  }

  device = argv[1];
  speed = B38400;
  if ( (strcmp(argv[2], "B9600") == 0) || (strcmp(argv[2], "9600") == 0) ) {
    speed = B9600;
  } else {
    fprintf(stderr, "Speed not recognized. Using B38400 instead.");
    speed = B38400;
  }

  if ( (strcmp(argv[3], "8N1") == 0) || (strcmp(argv[3], "8n1") == 0) ) {
    ctrllines = CS8;
  } else {
    fprintf(stderr, "Control lines not recognized. Using 8N1 instead.");
    ctrllines = CS8;
  }

  sendStr = argv[4];

  /* 
     Open modem device for reading and writing and not as controlling tty
     because we don't want to get killed if linenoise sends CTRL-C.
  */
  fd = open(device, O_RDWR | O_NOCTTY ); 
  if (fd <0) {
    fprintf(stderr, "Could not open %s.\n", device);
    exit(2);
  }
  
  tcgetattr(fd,&oldtio); /* save current serial port settings */
  bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
  
  /* 
     BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
     CRTSCTS : output hardware flow control (only used if the cable has
     all necessary lines. See sect. 7 of Serial-HOWTO)
     CS8     : 8n1 (8bit,no parity,1 stopbit)
     CLOCAL  : local connection, no modem contol
     CREAD   : enable receiving characters
  */
  //newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  newtio.c_cflag = ctrllines | CLOCAL;
  cfsetospeed(&newtio, speed);
  
  /*
    IGNPAR  : ignore bytes with parity errors
    ICRNL   : map CR to NL (otherwise a CR input on the other computer
    will not terminate input)
    otherwise make device raw (no other input processing)
  */
  newtio.c_iflag = IGNPAR | ICRNL;
  
  /*
    Raw output.
  */
  newtio.c_oflag = 0;
  
  /* 
     now clean the modem line and activate the settings for the port
  */
  tcflush(fd, TCIFLUSH);
  tcsetattr(fd,TCSANOW,&newtio);
  
  /*
    terminal settings done, now handle input
    In this example, inputting a 'z' at the beginning of a line will 
    exit the program.
  */
  running = TRUE;
  while (running == TRUE) {     
    for(i = 0; i < strlen(sendStr); i++) {
      printf("Sending char %c ...\n", sendStr[i]);
      write(fd, &sendStr[i], 1);
      sleep(1);
    }
    running = FALSE;
  }
  /* restore the old port settings */
  tcsetattr(fd,TCSANOW,&oldtio);

  return 0;
}
