//#include <stdio.h>
//#include <string>
//#include <stdlib.h>    //fuer atof
#include <fstream>       //includet auch iostream 
#include <unistd.h>      //read, write, close
#include <fcntl.h>
#include <sys/termios.h>
#include <sys/ioctl.h>


class Dmm {
  private:
    fstream me;
    int initTTY(char*);
  public:
    Dmm(char*);
    ~Dmm();
    int liesMesswert(); 
};


Dmm::Dmm(char* device){   //Konstruktor

  //initTTY(device);
  me.open(device, ios::app | ios::in);
  if (!me) {
    cerr<<"Device "<<device<<" kann nicht geoeffnet werden!"<< endl;
  exit(1); 
  }
  else {   
    cout << "Device " << device << endl;
  }

  initTTY(device);
} 

Dmm::~Dmm(){              //Destruktor
  me.close();
} 


int Dmm::initTTY(char* device){  //Initialisierung der Schnittstelle

  int modelines = 0;
  int fd = open(device, O_RDWR | O_NOCTTY);
  cout << "fd= " << fd << endl;
  if (fd == -1){
    cerr << "RS-232 kann nicht initialisiert werden!" << endl;
  exit(1);
  }


  struct termios settings;

  //Setzen der Inputflags
  settings.c_iflag = IGNBRK | IGNPAR;
  
  //Setzen der Outputflags
  settings.c_oflag = 0;
  
  //Setzen der Controlflags
  settings.c_cflag = CS7     // 7 Bit pro Byte
                   | CSTOPB  // 2 Stopbits
                   | CREAD   // Zeichen koennen von gelesen werden
                   | CLOCAL; // Ignoriere Modemstatus, lokaler Anschluss

  //Setzen der Localflags
  settings.c_lflag = 0;      // keine besonderen Angaben noetig

  // Maximale Zeit, die beim Lesen gewartet wird (in 0.1s)
  settings.c_cc[VTIME] = 10; // kleinere Werte für Geräte mit höheren
                             // Übertragungsgeschwindigkeiten 
                             // z.B. Me32 -> 30

  // Minimale Anzahl der zu lesenden Bytes
  settings.c_cc[VMIN] = 0;

  //Setzen der Uebertragungsgeschwindigkeit
  if (cfsetspeed(&settings, B2400)!=0){   //Me-22 hat jetzt 2400 Baud !!!
    cerr << "Fehler beim Setzen der Übertragungsgeschwindigkeit" << endl;
  return -1;
  }                 
 
  //Einstellungen an Schnittstelle uebergeben
  if (tcsetattr(fd, TCSANOW, &settings) == -1){
    cerr << "Fehler bei tcsetattr TCSANOW" << endl; 
  return -1;
  }    

  //Lesen der IO-Control Parameter
  if (ioctl(fd, TIOCMGET, &modelines) == -1){ 
    cerr << "Fehler bei ioctl TIOCMGET" << endl;
  return -1;
  }

  //Setzen des RTS-Signals, Spannungen an RTS-Leitung (?)
  modelines &= ~TIOCM_RTS;
  if (ioctl(fd,TIOCMSET,&modelines) == -1){ 
    cerr << "Fehler bei ioctl TIOCMSET" << endl;
  return -1;
  }

  close(fd);
}



int Dmm::liesMesswert(){
  me << "D\n" << endl;    //Messwert-String anfordern, "D\r" tuts auch

  char* header, einheit;  
  float messwert;

  me >> header >> messwert >> einheit;
  cout << header << " " << messwert << " " << einheit << endl; 
} 


int main(int argc, char* argv[]){

  Dmm* multimeter;

  if (argc > 1) multimeter = new Dmm(argv[1]);
  else          multimeter = new Dmm("/dev/ttyS0");

  for(int i = 1; i < 10; i++){   //kleine Schleife
    multimeter -> liesMesswert();
  }

  delete multimeter;

return 0;
}

