RFID::Reader::TCP - Abstract base class for RFID readers implemented over a TCP connection


RFID-Base documentation Contained in the RFID-Base distribution.

Index


Code Index:

NAME

Top

RFID::Reader::TCP - Abstract base class for RFID readers implemented over a TCP connection

SYNOPSIS

Top

This is an abstract base class used for building an RFID Reader class implemented over a TCP connection. It provides the basic I/O methods that an object based on RFID::Reader will expect, and generally a reader based on this class will simply inherit from it and add a few details. In other words, this class is fairly complete, and you shouldn't have to add much to it to make it workable.

DESCRIPTION

Top

Constructor

new

This constructor accepts all arguments to the constructor for IO::Socket::INET, and passes them along to it. Any other settings are intrepeted as parameters to the set method.

Currently, the Timeout parameter is sometimes ignored. That will be fixed in the future.

SEE ALSO

Top

RFID::Reader, RFID::Reader::Serial, IO::Socket::INET.

AUTHOR

Top

Scott Gifford <gifford@umich.edu>, <sgifford@suspectclass.com>

Copyright (C) 2004-2006 The Regents of the University of Michigan.

See the file LICENSE included with the distribution for license information.


RFID-Base documentation Contained in the RFID-Base distribution.
package RFID::Reader::TCP;
use RFID::Reader qw(ref_tainted); $VERSION=$RFID::Reader::VERSION;

# Written by Scott Gifford <gifford@umich.edu>
# Copyright (C) 2004-2006 The Regents of the University of Michigan.
# See the file LICENSE included with the distribution for license
# information.

use IO::Socket::INET;
use IO::Select;

sub new
{
    my $class = shift;
    my(%p)=@_;
    my $buf;

    my $self = {};
    bless $self,$class;

    # For IO::Socket::INET
    if ($p{timeout} && !$p{Timeout})
    {
	$p{Timeout}=$p{timeout};
    }

    $self->{_sock}=IO::Socket::INET->new(%p)
	or die "Couldn't create socket: $!\n";
    
    $self->{_select}=IO::Select->new($self->{_sock})
	or die "Couldn't create IO::Select: $!\n";

    # Clear out any gibberish that's waiting for us
    while ($self->{_select}->can_read(1))
    {
	($self->{_sock}->sysread($buf,8192));
	warn "Ignoring initial text '$buf'\n";
    }

    $self->_init(%p);

    $self;
}

sub _init
{
}

sub _readbytes
{
    my $self = shift;
    my($bytesleft)=@_;
    my $data = "";

    while($bytesleft > 0)
    {
	my $moredata;
	if ($self->{timeout})
	{
	    $self->{_select}->can_read($self->{timeout})
		or die "Read timed out.\n";
	}
	my $rb = $self->{_sock}->sysread($moredata,$bytesleft)
	    or die "Socket unexpectedly closed!\n";
	$bytesleft -= $rb;
	$data .= $moredata;
    }
    $data;
}

sub _readuntil
{
    my $self = shift;
    my($delim) = @_;

    local $/ = $delim;
    my $fh = $self->{_sock};
    defined(my $data = <$fh>)
	or die "Couldn't read from socket: $!\n";
    chomp($data);
    $data;
}

sub _writebytes
{
    my $self = shift;
    my $wb = join("",@_);
    if (ref_tainted(\$wb)) { die "Attempt to send tainted data to reader"; }
    if ($self->{timeout})
    {
	$self->{_select}->can_write($self->{timeout})
	    or die "Write timed out.\n";
    }
    $self->{_sock}->syswrite($wb);
}

sub _connected
{
    return $self->{_sock};
}

1;