package X10::Network; use vars qw(@ISA); @ISA = qw(X10::Controller); # this is an X10::Controller-type object, used to control X10 devices # via a process running an X10::Server object somewhere else use Storable qw(thaw); use IO::Socket; use strict; use X10::Controller; ### constructors sub new { my $type = shift; my $self = new X10::Controller( @_ ); bless $self, $type; $self->{socket} = new IO::Socket( Domain => &AF_INET, Proto => 'tcp', PeerAddr => $self->{server} || 'x10', PeerPort => $self->{server_port} || 2020, ); unless ($self->{socket}) { warn "Problem connecting socket: ", $!; return undef; } return $self; } ### public methods (most overriding parent class) sub select_fds { my $self = shift; return ($self->{socket}->fileno); } sub handle_input { my $self = shift; $self->get_event; } sub send { my $self = shift; foreach (@_) { $self->send_one($_); } } sub send_one { my $self = shift; my $event = shift; my $packet = $event->nfreeze; $self->{socket}->syswrite(chr(length($packet)), 1); $self->{socket}->syswrite($packet, length($packet)); } sub get_event { my $self = shift; my $size; my $bytes_read = $self->{socket}->sysread($size, 1); unless ($bytes_read == 1) { $self->{socket}->close; die "Lost connection to X10 server: ", $!; } $size = ord($size); my $packet = ''; $bytes_read = $self->{socket}->sysread($packet, $size); unless ($bytes_read == $size) { $self->{socket}->close; die "Lost connection to X10 server: ", $!; } my $event = thaw($packet); next undef unless $event; unless ($event->isa('X10::Event')) { warn "Unknown packet type: ", ref $event; return undef; } $self->got_event($event); return $event; } ### mostly-private methods... sub DESTROY { my $self = shift; $self->{socket}->close; } ### utility functions -- not called as methods 1;