use strict;
use warnings;
use Win32::SerialPort;
use Term::ReadKey;

my ($char, $num, $run);

my $port = Win32::SerialPort->new('COM1')
    or die "Oops!\n";

$| = 1;

# Parameter setzen
$port->baudrate(19200)    || die "baudrate geht nicht\n";
$port->parity('none')	    || die "parity geht nicht\n";
$port->databits(8)        || die "databits geht nicht\n";
$port->stopbits(1)        || die "stopbits geht nicht\n";
$port->handshake("rts") 	|| die "handshake geht nicht\n";
# defined, weil "0" ein legaler Rueckgabewert ist
defined $port->parity_enable('T')	|| die "parity_enable geht nicht\n";

# Devicecontrolblock schreiben
$port->write_settings	    || die "write_setings geht nicht\n";

# Fehlermeldungen einschalten
$port->error_msg(1);
$port->user_msg(1);

# Wartezeit fuer Lesen eines Zeichens
$port->read_char_time(1);
# Wartezeit fuer Lese-Overhead
$port->read_const_time(10);

# Setup fuer dummes Terminal,
# kann je nach Anwendung variieren
$port->stty_icrnl(1);
$port->stty_ocrnl(0);  #
$port->stty_onlcr(0);  #
$port->stty_opost(1);

# Signalhandler fuer Stg-C
$SIG{INT}  = sub { $run = 0 };

# Modem Einstellen, Konfiguration auslesen
# letztere Kommt in drei Abteilungen
WriteData($port, "ATX4E0&V\r");
print ReadData($port, 100);
WriteData($port, "\r");
print ReadData($port, 100);
WriteData($port, "\r");
print ReadData($port, 100);

$port -> close();
undef $port;


sub WriteData # $port, $data
  {
  # Sendefunktion
  my ($num, $char, $cc);
  my $port = shift;
  my $string = shift;
  for $char (split(//, $string))
    {
    # Behandlung von Carriage Return und Line Feed
	  $char =~ s/\r/\n/ogs if ($port->stty_ocrnl);
	  $char =~ s/\n/\r\n/ogs if ($port->stty_opost && $port->stty_onlcr);
	  # Zeichen auf der seriellen Schnittstelle ausgeben
    $port->write($char);
    ($num, $cc) = $port->read(1);
    if ($num > 0)
      {
      # Behandlung von Carriage Return und Line Feed
  	  $cc =~ s/\r/\n/ogs if ($port->stty_icrnl);
	    # auf dem Bildschirm ausgeben
	    print $cc;
      }
    }
  }


sub ReadData # $port, $maxtries
  {
  # Eingabefunktion
  my $port = shift;
  my $maxtries = shift;
  my $tries = 0;
  my $buffer = '';

  while ($tries < $maxtries)
    {
    # Daten lesen (Anzahl Daten, Datenstring)
    my ($num, $data) = $port->read(1);
    # Behandlung von Carriage Return und Line Feed
	  $data =~ s/\r/\n/ogs if ($port->stty_icrnl);
    $buffer .= $data;        # Daten in den Puffer
    # falls keine Daten gelesen wurden, Versuche
    # hochzaehlen, andernfalls nullsetzen
    $tries = ($num == 0) ? $tries + 1 : 0;
    }
  return $buffer;
  }