use POSIX qw(:termios_h); use FileHandle; # usage: $serial=init_serial("/dev/modem",38400,"8n1"); # you can then use sysread/write on $serial, which is a file handle. sub init_serial { my($port,$baud,$pref)=@_; my($termios,$cflag,$lflag,$iflag,$oflag); my($voice); my $serial=new FileHandle("+>$port") || die "Could not open $port: $!\n"; $termios = POSIX::Termios->new(); $termios->getattr($serial->fileno()) || die "getattr: $!\n"; $cflag= 0 | CS8 | HUPCL | CREAD | CLOCAL; $lflag= 0; $iflag= 0 | IGNBRK | IGNPAR | IXON | IXOFF; $oflag= 0; $termios->setcflag($cflag); $termios->setlflag($lflag); $termios->setiflag($iflag); $termios->setoflag($oflag); $termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n"; eval qq[ \$termios->setospeed(POSIX::B$baud) || die "setospeed: \$!\n"; \$termios->setispeed(POSIX::B$baud) || die "setispeed: \$!\n"; ]; die $@ if $@; $termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n"; if ($pref =~ /7e1/) { print "Switching to 7e1 mode\n"; $termios->getattr($serial->fileno()) || die "getattr: $!\n"; $cflag= 0 | CS7 | HUPCL | CREAD | CLOCAL | PARENB; $iflag= 0 | IGNBRK | IGNPAR | IXON | IXOFF; $oflag= 0; $lflag= 0; $termios->setcflag($cflag); $termios->setlflag($lflag); $termios->setiflag($iflag); $termios->setoflag($oflag); $termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n"; eval qq[ \$termios->setospeed(POSIX::B$baud) || die "setospeed: \$!\n"; \$termios->setispeed(POSIX::B$baud) || die "setispeed: \$!\n"; ]; die $@ if $@; $termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n"; } # This gets rid of all the special characters.. $termios->getattr($serial->fileno()) || die "getattr: $!\n"; for (0..NCCS) { if ($_ == NCCS) { last; } # Dont mess up XON/XOFF.. if ($_ == VSTART || $_ == VSTOP) { next; } $termios->setcc($_,0); } $termios->setattr($serial->fileno(),TCSANOW) || die "setattr: $!\n"; return $serial; } 1;