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

void readTimeoutCheck(int intDD, struct termios objSO);
void sigint_handler(int sig);
int  sig_int=0;

int main(int argc, char *argv[]){
  int fd,nread,st,step;
  struct termios old_options,new_options;
  char msg[256];

  if(argc!=2){
    printf("Usage: fine501 step \n");
    exit(1);
  }
  sscanf(argv[1],"%d",&step);
  if(step<-8000 || step>120000){
    printf("step must be -8000 to 120000\n");
    exit(1);
  }

  signal(SIGINT, sigint_handler);
  fprintf(stderr,"Open device.\n");
  if ((fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY)) == -1) {
    fprintf(stderr,"#device is not ready.\n");
    return 1;
  }
  tcgetattr(fd, &old_options);
  bzero(&new_options, sizeof(new_options));
  new_options.c_cflag = B9600 | CS8 | CLOCAL | CREAD | CRTSCTS;
  new_options.c_lflag = ICANON;
  tcflush(fd, TCIFLUSH);
  fprintf(stderr,"Set options (%x/%x).\n",new_options.c_cflag,new_options.c_lflag);
  tcsetattr(fd, TCSANOW, &new_options);

  if(step>=0) sprintf(msg,"A:1+P%d\015\012",step);
  else sprintf(msg,"A:1-P%d\015\012",-step);
  fprintf(stderr,"%s\n",msg);
  write(fd, msg, strlen(msg));
  strcpy(msg,"G:\015\012");
  fprintf(stderr,"%s\n",msg);
  write(fd, msg, strlen(msg));

  st=0;
  while(sig_int==0 && st==0){
    usleep(100000);
    //strcpy(msg,"?:N\015\012");
    strcpy(msg,"!:\015\012");
    fprintf(stderr,"%s\n",msg);
    write(fd, msg, strlen(msg));
    readTimeoutCheck(fd, old_options);
    nread = read(fd, msg, sizeof(msg));
    msg[nread - 2]='\0';
    fprintf(stderr,"Reply: %s\n",msg);
    if(strcmp(msg,"R")==0) st=1;
  }

  fflush(stdout);
  fprintf(stderr,"Restore options.\n");
  tcsetattr(fd, TCSANOW, &old_options);
  close(fd);
}

void readTimeoutCheck(int intDD, struct termios objSO)
{
  int              ret;
  fd_set           rfds;
  struct timeval   timeout;

  timeout.tv_sec =  3;
  timeout.tv_usec = 0;

  FD_ZERO(&rfds);
  FD_SET(intDD, &rfds);

  ret = select(intDD+1, &rfds, NULL, NULL, &timeout);

  if(ret == 0){
    printf("conection timeout.\n");
    fflush(stdout);
    fprintf(stderr,"Restore options.\n");
    tcsetattr(intDD, TCSANOW, &objSO);
    close(intDD);
    exit(1);
  }
}

void sigint_handler(int sig)
{
  sig_int=1;
  signal(SIGINT, sigint_handler);
}
