Does anybody have some working code using Win32::SerialPort with POE?

I've tried to follow the example in the cookbook, but haven't been able to get very far. I injected a FILENO method. Unfortunately, I never seem to get any data from my comm port. Is this due to the broken socket-only select on Windows?

My code (which is essentially the cookbook recipe minus the wheel for terminal IO, and an injected FILENO method for Win32::SerialPort) follows below:

#!/usr/bin/perl

use warnings;
use strict;

$| = 1;

use POE;
use POE::Wheel::ReadWrite;

use Symbol qw(gensym);
use Win32::SerialPort;
BEGIN {
   package Win32::SerialPort;

   sub FILENO {
       my $self = shift;
# The _HANDLE value of the object contains the file descriptor that # was returned by CreateFile() which the docs say is a file descriptor.
       my $handle = $self->{_HANDLE};
       return $handle || -1;
   }

}


use POE::Filter::Line;

POE::Session->create(
   inline_states => {
       _start      => \&setup_device,
       got_port    => \&display_port_data,
       got_console => \&transmit_console_data,
       got_error   => \&handle_errors,
   },
);

POE::Kernel->run();
exit 0;

sub setup_device {
   my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];

   warn "setup\n";

   # Open a serial port, and tie it to a file handle for POE.
   my $handle = gensym();

   my  $port = tie( *$handle, 'Win32::SerialPort', 'poeterm.conf' );
   die "can't open port: $!" unless $port;

   warn "setup has port\n";

   $port->datatype('raw');
   $port->baudrate(9600);
   $port->databits(8);
   $port->parity("none");
   $port->stopbits(1);
   $port->handshake('none');
   $port->write_settings();

   # Start interacting with the GPS.

   $heap->{port}       = $port;
   $heap->{port_wheel} = POE::Wheel::ReadWrite->new(
       Handle => $handle,
       InputEvent => "got_port",
       ErrorEvent => "got_error",
   );

   warn "setup almost done\n";
   # Start a wheel to interact with the console, and prompt the user.

}

# Port data (lines, separated by CRLF) are displayed on the console.
sub display_port_data {
   my ( $heap, $data ) = @_[ HEAP, ARG0 ];
   print STDOUT $data;
}

# Console input is sent to the device.
sub transmit_console_data {
   my ( $heap, $input ) = @_[ HEAP, ARG0 ];
   # Not really.
}

# Error on the serial port.  Shut down.
sub handle_errors {
   my $heap = $_[HEAP];

   delete $heap->{port_wheel};
}

Reply via email to