#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
use IO::Select;
use XML::Simple;
use Device::Conf "EscapeList";

my $BCAST_ADDR = '192.168.0.255';
my $BCAST_PORT = 1757;
my $MAX_WAIT = 5; # Max 5 sec to wait for answers

my $rand_max = 2 ** 32 - 1;
my $t_start = time;

# Create broadcast socket
my $socket = IO::Socket::INET->new(Proto => 'udp') or die "socket: $!";
$socket->sockopt(SO_BROADCAST() => 1) or die "sockopt: $!";
my $dest = sockaddr_in($BCAST_PORT,inet_aton($BCAST_ADDR));

bind($socket, sockaddr_in($BCAST_PORT, INADDR_ANY)) or die "bind: $!";

my $select = IO::Select->new($socket);

# Send broadcasr request
my $req = "\x99\x39\xA4\x27".pack('N',int(rand($rand_max)))."\x00\x00".pack('n',$BCAST_PORT);
send($socket,$req,0,$dest);
# Wait for response

my $result = "";
my @devs;
while(time - $t_start < $MAX_WAIT) {
    if ($select->can_read(1)) {
	my $data;
	my $from = recv($socket,$data,1024,0) or die "recv: $!";
	my ($port,$peer) = sockaddr_in($from);
	my $host = inet_ntoa($peer);
	
	my $xml = eval { XMLin $data };
	next if $@;
	next if not $xml->{device};
	
	my $http_port = $xml->{device}{HTTPPort};
	my $ip = $xml->{device}{unitIPAddress};
	my $name = $xml->{device}{friendlyName};
	$name =~ s/\n/ /;
	
	next if not $ip or not $http_port;
	
	push @devs, {NAME=>$name,HTTP_PORT=>$http_port,DEVIP=>$ip};
    }
}

print EscapeList(%$_),"\n" foreach @devs;
