/*
    Read measurement values from METEX M-3850M
    Copyright (C) 2003  Wiesner Thomas^M
^M
    This program is free software; you can redistribute it and/or modify^M
    it under the terms of the GNU General Public License as published by^M
    the Free Software Foundation; either version 2 of the License, or^M
    (at your option) any later version.^M
^M
    This program is distributed in the hope that it will be useful,^M
    but WITHOUT ANY WARRANTY; without even the implied warranty of^M
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the^M
    GNU General Public License for more details.^M
^M
    You should have received a copy of the GNU General Public License^M
    along with this program; if not, write to the Free Software^M
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN^M
    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES^M
    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED^M
    OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF^M
    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS^M
    TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE^M
    PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,^M
    REPAIR OR CORRECTION.
*/

#include <stdio.h>
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

struct termios oldser;
int oldline;

int init_dmm(char *file)
{
   struct termios serterm;
   int linemode;
   int fd, buf;

   if((fd = open(file, O_RDWR | O_NOCTTY)) < 0)
      return -1;
   if(!isatty(fd))
      return -2;

   serterm.c_iflag = IGNBRK | IGNPAR;
   serterm.c_oflag = 0;
   serterm.c_cflag = CS7 | CSTOPB | CREAD | CLOCAL | B9600;
   serterm.c_lflag = 0;
   serterm.c_cc[VTIME] = 20;
   serterm.c_cc[VMIN] = 0;

   if(tcgetattr(fd, &oldser) < 0)
      return -3;
   if(tcsetattr(fd, TCSANOW, &serterm) < 0)
      return -4;
   if(ioctl(fd, TIOCMGET, &linemode) < 0)
      return -5;
   oldline = linemode;
   linemode &= ~TIOCM_RTS;
   if(ioctl(fd, TIOCMSET, &linemode) < 0)
      return -6;

   // Read out and throw away anything stil in
   // the input buffer (takes timeout)
   // Otherwise, we get strange results
   while(read(fd, &buf, 1) > 0)
      ;

   return fd;
}

int read_dmm(int fd, char *data)
{
   int i;

   write(fd, "D", 1);
   for(i = 0; i < 56; i++) {
      if(read(fd, &data[i], 1) != 1) {
         printf("Timeout\n");
         return -1;
      }
   }
   return 0;
}

int close_dmm(int fd)
{
   if(tcsetattr(fd, TCSANOW, &oldser) < 0)
      return -1;
   if(ioctl(fd, TIOCMSET, &oldline) < 0)
      return -2;
   return (close(fd));
}

int main(int argc, char *argv[])
{
   int num, i, j;
   int del;
   int sfd;
   char buf[56];

   if(argc != 4) {
      printf("%s device count delay (seconds)\n"
            "if delay is 0 seconds, the refresh speed is limited by the DMM\n"
            "Please note, that the time isn't too accurate, because the dmm\n"
            "needs some time to convert and send the value.\n", argv[0]);
      return -1;
   }

   if((sfd = init_dmm(argv[1])) < 0) {
      printf("Error on opening device\n");
      return -2;
   }
   num = atoi(argv[2]);
   del = atoi(argv[3]);

   for(i = 0; i < num; i++) {
      if(read_dmm(sfd, buf) >= 0) {
         for(j = 0; j < 56; j++) {
            if(buf[j] != '\r')
               putchar(buf[j]);
            else {
               putchar('\t');
            }
         }
      }
      putchar('\n');
      fflush(stdout);
      if(del != 0)
         sleep(del);
   }
   close_dmm(sfd);
   return 0;
}