Win32::SerialPort and POE

Mark Swayne <[email protected]>
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
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};
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.