File Coverage

blib/lib/POE/Component/WakeOnLAN.pm
Criterion Covered Total %
statement 61 65 93.8
branch 7 16 43.7
condition 4 11 36.3
subroutine 10 10 100.0
pod 1 1 100.0
total 83 103 80.5


line stmt bran cond sub pod time code
1             package POE::Component::WakeOnLAN;
2             {
3             $POE::Component::WakeOnLAN::VERSION = '1.04';
4             }
5              
6             #ABSTRACT: A POE Component to send packets to power on computers.
7              
8 1     1   960 use strict;
  1         2  
  1         37  
9 1     1   6 use warnings;
  1         1  
  1         41  
10 1     1   6 use Socket;
  1         2  
  1         955  
11 1     1   11 use Carp;
  1         2  
  1         59  
12 1     1   5 use IO::Socket::INET;
  1         2  
  1         15  
13 1     1   4082 use Net::IP::Minimal;
  1         1047  
  1         67  
14 1     1   7 use POE;
  1         3  
  1         10  
15              
16             sub wake_up {
17 1     1 1 1373 my $package = shift;
18 1         5 my %params = @_;
19 1         9 $params{lc $_} = delete $params{$_} for keys %params;
20 1 50       6 croak "$package wake_up requires a 'macaddr' parameter\n" unless $params{macaddr};
21 1 50       4 croak "$package wake_up requires an 'event' parameter\n" unless $params{event};
22 1         6 $params{macaddr} =~ s/://g;
23 1 50 33     9 $params{port} = 9 unless $params{port} and $params{port} =~ /^\d+$/;
24 1 50 33     6 $params{address} = '255.255.255.255' unless $params{address} and Net::IP::Minimal::ip_get_version( $params{address} );
25 1         2 my $options = delete $params{options};
26 1         3 my $self = bless \%params, $package;
27 1 50       19 $self->{session_id} = POE::Session->create(
28             object_states => [
29             $self => [qw(_start _ready)],
30             ],
31             heap => $self,
32             ( ref($options) eq 'HASH' ? ( options => $options ) : () ),
33             )->ID();
34 1         394 return $self;
35             }
36              
37             sub _start {
38 1     1   186 my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER];
39 1         3 $self->{session_id} = $_[SESSION]->ID();
40 1 50 33     10 if ( $kernel == $sender and !$self->{session} ) {
41 0         0 croak "Not called from another POE session and 'session' wasn't set\n";
42             }
43 1         11 my $sender_id;
44 1         2 my $session = delete $self->{session};
45 1 50       3 if ( $session ) {
46 0 0       0 if ( my $ref = $kernel->alias_resolve( $self->{session} ) ) {
47 0         0 $sender_id = $ref->ID();
48             }
49             else {
50 0         0 croak "Could not resolve 'session' to a valid POE session\n";
51             }
52             }
53             else {
54 1         4 $sender_id = $sender->ID();
55             }
56 1         9 $kernel->refcount_increment( $sender_id, __PACKAGE__ );
57 1         35 $self->{sender_id} = $sender_id;
58 1   50     11 my $sock = new IO::Socket::INET(Proto=>'udp') || return;
59 1         378 my $ip_addr = inet_aton( $self->{address} );
60 1         6 my $sock_addr = sockaddr_in($self->{port}, $ip_addr);
61 1         21 my $packet = pack('C6H*', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, $self->{macaddr} x 16);
62 1         6 $kernel->select_write( $sock, '_ready' );
63 1         197 setsockopt($sock, SOL_SOCKET, SO_BROADCAST, 1);
64 1         313 send($sock, $packet, 0, $sock_addr);
65 1         6 return;
66             }
67              
68             sub _ready {
69 1     1   326 my ($kernel,$self,$socket) = @_[KERNEL,OBJECT,ARG0];
70 1         5 $kernel->select_write( $socket );
71 1         131 my $response = { };
72 1         2 $response->{$_} = $self->{$_} for keys %{ $self };
  1         12  
73 1         28 delete $response->{session_id};
74 1         3 my $sender_id = delete $response->{sender_id};
75 1         3 my $event = delete $response->{event};
76 1         7 $kernel->post( $sender_id, $event, $response );
77 1         105 $kernel->refcount_decrement( $sender_id, __PACKAGE__ );
78 1         48 return;
79             }
80              
81             1;
82              
83              
84             __END__