#!/usr/bin/perl
#------------------------------------------------------------------------------
# print list of all IQEye cameras in network
# in next the format:
# NAME:name,DEVIP:ip,HTTP_PORT:port
#------------------------------------------------------------------------------
# Author: Alexey Tsibulnik
# Edited by:
# QA by:
# Copyright: videoNEXT Network Solutions LLC 2006
#-----------------------------------------------------------------------------
use strict;
use Net::DNS;
use IO::Select;
use IO::Socket::Multicast;
use Device::Conf "EscapeList";

# mDNS params
my $DNS_SERVER = '224.0.0.251';
my $DNS_PORT = 5353;
my $DNS_DOMAIN = 'local';
# IQEye discover params
my $SERVICE = 'http';
my $PROTO = 'tcp';
my $FQDN = sprintf '_%s._%s.%s', $SERVICE, $PROTO, $DNS_DOMAIN;
my $MAX_WAIT = 5;

# Construct mDNS query
my $query = Net::DNS::Packet->new($FQDN, 'PTR', 'IN');
my $header = $query->header;
$header->rd(0); # No recursion
$header->id(0);
$query->header($header);

# Create multicast socket and join group
my $socket = IO::Socket::Multicast->new(LocalPort=>$DNS_PORT,ReuseAddr=>1);
$socket->mcast_add($DNS_SERVER) || die "Couldn't set group: $!\n";

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

send $socket, $query->data, 0, sockaddr_in($DNS_PORT, inet_aton($DNS_SERVER));

my $t_start = time;
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($ans,$err) = Net::DNS::Packet->new(\$data);
	next if $query->header->id != $ans->header->id;
	
	my @add = $ans->additional;
	my $is_iqeye = 0;
	do { $is_iqeye = 1,last if $_->string=~/iqinvision/i} foreach @add;
	next unless $is_iqeye;
	
	# Extract data from records
	my ($ip,$name,$http_port);
	foreach my $rr (@add) {
	    if ($rr->type eq 'A') {
		$ip = $rr->address;
	    }
	    elsif ($rr->type eq 'SRV') {
		$http_port = $rr->port;
	    }
	    elsif ($rr->type eq 'TXT') {
		foreach ($rr->char_str_list) {
		    my ($attr,$val) = /^(.+)=(.+)$/;
		    $name = $val,last if $attr=~/server name/i;
		}
	    }
	}
	
	push @devs, {NAME=>$name,DEVIP=>$ip,HTTP_PORT=>$http_port};
    }
}

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