#!/usr/bin/perl -w
#
# create a terrestrial.xml for neutrino from the data installed by the
# dvb utils
# the behaviour is similar to the "scan" program form the dvb utils.
#
# Released under the GPL V2 or later
# (C) 2009-2012 Stefan Seyfried

use strict;
my $srcdir = "/usr/share/dvb/dvb-t";

# can be given as "de-*"
my $scanfile = shift;
$scanfile = "auto-Default" unless (defined $scanfile);

my @sourcefiles = glob($srcdir . "/" . $scanfile);
my ($sourcefile, $basename, $line, $k);
my ($freq, $bw, $cr_hp, $cr_lp, $mod, $tmode, $gint, $hier);

# from /usr/include/linux/dvb/frontend.h
# inversion is not used in the scan files
my %INV = ("INVERSION_OFF" => 0, "INVERSION_ON" => 1, "INVERSION_AUTO" => 2);
my %CODE_RATE = ("NONE" => 0, "1/2" => 1, "2/3" => 2, "3/4" => 3, "4/5" => 4,
		 "5/6" => 5, "6/7" => 6, "7/8" => 7, "8/9" => 8, "AUTO" => 9);
my %MODULATION = ("QPSK" => 0, "QAM16" => 1, "QAM32" => 2, "QAM64" => 3,
		  "QAM128" => 4, "QAM256" => 5, "AUTO" => 6);
my %T_MODE = ("2k" => 0, "8k" => 1, "AUTO" => 2);
my %BWIDTH = ("8MHz" => 0, "7MHz" => 1, "6MHz" => 2, "AUTO" => 3);
my %GINTERVAL = ("1/32" => 0, "1/16" => 1, "1/8" => 2, "1/4" => 3, "AUTO" => 4);
my %HIERARCHY = ("NONE" => 0, "1" => 1, "2" => 2, "4" => 3, "AUTO" => 4);


# print the header
print("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
print("<!-- useable flags are
	1 - Network Scan
	2 - use BAT
	4 - use ONIT
	8 - skip NITs of known networks
	and combinations of this -->\n\n");
print("<!-- this file is autogenerated by mk_terrestrial_xml.pl
     WARNING! It is probably unsuitable for enigma! -->\n");
#
# explain the parameters
print("<!-- Parameters are (unfortunately, the neutrino parser does not allow default settings,
     the default is always \"0\"):\n");
print("\t* bandwidth:\n\t\t");
foreach $k (sort {$BWIDTH{$a} <=> $BWIDTH{$b}} keys %BWIDTH) { printf("\"%d\"-%s ", $BWIDTH{$k}, $k); }
print("\n\t* constellation:\n\t\t");
foreach $k (sort {$MODULATION{$a} <=> $MODULATION{$b}} keys(%MODULATION)) { printf("\"%d\"-%s ", $MODULATION{$k}, $k); }
print("\n\t* transmission_mode:\n\t\t");
foreach $k (sort {$T_MODE{$a} <=> $T_MODE{$b}} keys(%T_MODE)) { printf("\"%d\"-%s ", $T_MODE{$k}, $k); }
print("\n\t* code_rate_[HL]P:\n\t\t");
foreach $k (sort {$CODE_RATE{$a} <=> $CODE_RATE{$b}} keys(%CODE_RATE)) { printf("\"%d\"-%s ", $CODE_RATE{$k}, $k); }
print("\n\t* guard_interval:\n\t\t");
foreach $k (sort {$GINTERVAL{$a} <=> $GINTERVAL{$b}} keys(%GINTERVAL)) { printf("\"%d\"-%s ", $GINTERVAL{$k}, $k); }
print("\n\t* hierarchy:\n\t\t");
foreach $k (sort {$HIERARCHY{$a} <=> $HIERARCHY{$b}} keys(%HIERARCHY)) { printf("\"%d\"-%s ", $HIERARCHY{$k}, $k); }
print("\t-->\n\n");
# header ends...

print("<locations>\n");
foreach $sourcefile (@sourcefiles)
{
	open(FILE, "< $sourcefile") or die "can't open $sourcefile: $!\n";
	$basename = $sourcefile;
	$basename =~ s#^.*/##;
	print("\t<terrestrial name=\"$basename\" flags=\"5\">\n");
	while ($line = <FILE>)
	{				# T 184500000 7MHz     3/4     NONE   QAM16     8k     1/4    NONE
		next unless ($line =~ m/^T\s+(\d+)\s+(\dMHz)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/);
		$freq = $1; $bw = $2; $cr_hp = $3; $cr_lp = $4; $mod = $5; $tmode = $6; $gint = $7; $hier = $8;
		unless (defined($CODE_RATE{$cr_hp}))	{ warn "$basename: illegal cr_hp: $cr_hp, using AUTO\n"; $cr_hp="AUTO" };
		unless (defined($CODE_RATE{$cr_lp}))	{ warn "$basename: illegal cr_lp: $cr_lp, using AUTO\n"; $cr_lp="AUTO" };
		unless (defined($MODULATION{$mod}))	{ die "$basename: illegal mod: $mod\n" }; # no errors in those (yet).
		unless (defined($T_MODE{$tmode}))	{ die "$basename: illegal tmode: $tmode\n" };
		unless (defined($GINTERVAL{$gint}))	{ die "$basename: illegal gint: $gint\n" };
		unless (defined($HIERARCHY{$hier}))	{ die "$basename: illegal hier: $hier\n" };
		unless (defined($BWIDTH{$bw}))		{ die "$basename: illegal bw: $bw\n" };
		if ($cr_hp eq "NONE") { $cr_hp="AUTO" }; # same as scan.c
		if ($cr_lp eq "NONE") { $cr_lp="AUTO" }; # same as scan.c
		printf("\t\t<transponder frequency=\"%d\" bandwidth=\"%d\" constellation=\"%d\" ".
		       "transmission_mode=\"%d\" code_rate_HP=\"%d\" code_rate_LP=\"%d\" ".
		       "guard_interval=\"%d\" hierarchy=\"%d\" />\n",
			$freq / 1000, $BWIDTH{$bw}, $MODULATION{$mod},
			$T_MODE{$tmode}, $CODE_RATE{$cr_hp}, $CODE_RATE{$cr_lp},
			$GINTERVAL{$gint}, $HIERARCHY{$hier});
	}
	print("\t</terrestrial>\n");
}
print("</locations>\n");
