#!/usr/bin/perl -w
# Ben Kramer
# 24/08/2005
# Ron Lee
# 4/11/2006
#
# This program should auto detect what cards are in the system
# ask the appropriate questions to determine their configuration
# and create the config files for them all!

use strict;
use warnings;

#use Data::Dumper;

sub proc_isdn();
sub proc_ana();
sub proc_vpbconf();

my $VPBSCAN     = "/usr/sbin/vpbscan";

my $vpbconfdir  = "/etc/vpb";
my $priconfdir  = "/etc/wanpipe";

my $cardcount   = 0;
my $configcount = 0;
my $spancount   = 0;
my $cards;
my $configs;
my $spans;

print "\nWelcome to the VoiceTronix Configurator 4.2.23.\n";
print "This will scan the PCI bus to determine what cards you have\n";
print "and create the default config files they require.\n\n";

# Check if we are the root user
my $NAME = `/usr/bin/whoami`;
chomp($NAME);
my $UID = getpwnam($NAME);
if ($UID != 0){
	print "You must be root to create the config files in $vpbconfdir\n\n";
	exit 1;
}

# Check we aren't going to stomp an existing config
if ( -e $vpbconfdir ){
	print "The config dir $vpbconfdir already exists.\n";
	print "Please remove it first if you really wish to regenerate it.\n\n";
	exit 1;
}

# Scan to see what we have
print "Scanning PCI bus....\n";
my @conf = `$VPBSCAN 2>&1`;
if( $? != 0 ){
	printf STDERR "Failed to read hardware config: @conf\n";
	exit 1;
}
foreach my $line (@conf) {
	if ($line =~ "CARD"){
		$line =~ s/\n//;
		$cardcount++;
		my($junk,$type,$junk2,$bus,$dev)=split ":",$line;
		$cards->{$cardcount}{"type"}=$type;
		$cards->{$cardcount}{"bus"}=$bus;
		$cards->{$cardcount}{"dev"}=$dev;
	}
}
if ($cardcount == 0){
	print "There are no Voicetronix cards installed in this system\n";
	exit 0;
}

print "found $cardcount cards.\n\n";

print "Please enter your country code (eg. 61 for AU, 1 for US): ";
my $country_code = readline STDIN;
chomp($country_code);

print "Processing ISDN cards...\n";
proc_isdn();

print "Processing Analog cards...\n";
proc_ana();

print "Created $configcount card config files...\n";
print "On a total of $spancount 'spans'...\n";
proc_vpbconf();

print "Done\n";
#print Dumper($cards);
exit 0;


sub proc_ana()
{ #{{{
	my $os12=0;
	my $os12s;
	my $ol4=0;
	my $ol4s;
	my $op=0;
	my $ops;

	foreach my $cardnum (sort keys %{$cards}){
		if ($cards->{$cardnum}{"type"} eq "V12PCI"){
			$os12++;
			$os12s->{$os12}=$cards->{$cardnum};
		}
		elsif ($cards->{$cardnum}{"type"} eq "V4PCI"){
			$ol4++;
			$ol4s->{$ol4}=$cards->{$cardnum};
		}
		elsif ($cards->{$cardnum}{"type"} eq "OPENPCI"){
			$op++;
			$ops->{$op}=$cards->{$cardnum};
		}
	}
	print "Found $ol4 OpenLine4's, $os12 OpenSwitch12's and $op OpenPCI's.\n";
	#print Dumper($os12s);

	if ($ol4 != 0){
		print "Creating OpenLine4 config file...\n";
		mkdir $vpbconfdir;
		open FILE,">","$vpbconfdir/openline.conf";
		print FILE "[general]\n";
		print FILE "name  = openline\n";
		print FILE "cards = $ol4\n\n";
		for(my $i = 0; $i < $ol4; $i++) {
			print "Is OpenLine4 #$i configured for logging only, with jumpers H1 to H4 removed? (y/n)";
			my $ch = readline STDIN;
			if ($ch =~ /^y/i) {
				$spans->{$spancount}="openlog:$i";
			} else {
				$spans->{$spancount}="openline:$i";
			}
			$spancount++;
			print FILE "[card$i]\n";
			print FILE "type = OpenLine4\n";
			print FILE "#bal$_ =\n"   foreach (1 ... 3);
			print FILE "#hwplaygain =\n";
			print FILE "#hwrecordgain =\n";
			print FILE "#playgain =\n";
			print FILE "#recordgain =\n";
			print FILE "#chan = $_\n" foreach (0 ... 3);
			print FILE "\n";
		}
		close FILE;
		$configcount++;
		$configs->{$configcount}->{"type"}="V4PCI";
		$configs->{$configcount}->{"name"}="openline.conf";
		$configs->{$configcount}->{"count"}=$ol4;
		print "Created OpenLine4 config file\n";
	}
	if (($op!=0)||($os12!=0)){
		my $cards  = 0;
		$cards += $op;
		$cards += $os12;

		print "Creating VTCore config file...\n";
		mkdir $vpbconfdir;
		open FILE,">","$vpbconfdir/vtcore.conf";
		print FILE "[general]\n";
		print FILE "name  = vtcore\n";
		print FILE "cards = $cards\n\n";
		my $x=0;
		for(my $i = 0; $i < $op; $i++) {
			$spans->{$spancount}="openpci:$x";
			$spancount++;
			print FILE "[card$x]\n";
			print FILE "type = OpenPCI\n";
			print FILE "#country = $country_code\n";
			print FILE "#fxs_impedance = 4\n";
			print FILE "#fxo_impedance = 2\n";
			print FILE "#logging = 1\n";
			print FILE "#hwplaygain =\n";
			print FILE "#hwrecordgain =\n";
			print FILE "#playgain =\n";
			print FILE "#recordgain =\n";
			print FILE "#dtmfms =\n";
			print FILE "#cutthrough =\n";
			print FILE "#chan = $_\n" foreach (0 ... 7);
			print FILE "\n";
			$x++;
		}
		if ($os12 != 0){
			for(my $i = 0; $i < $os12; $i++){
				$spans->{$spancount}="openswitch:$x";
				$spancount++;
				print FILE "[card$x]\n";
				print FILE "type = OpenSwitch12\n";
				print FILE "#country = $country_code\n";
				print FILE "#logging = 1\n";
				print FILE "#bal$_ =\n"   foreach (1 ... 3);
				print FILE "#hwplaygain =\n";
				print FILE "#hwrecordgain =\n";
				print FILE "#playgain =\n";
				print FILE "#recordgain =\n";
				print FILE "#dtmfms =\n";
				print FILE "#cutthrough =\n";
				print FILE "#chan = $_\n" foreach (0 ... 11);
				print FILE "\n";
				$x++;
			}
		}
		close FILE;
		$configcount++;
		$configs->{$configcount}->{"type"}="VTCORE";
		$configs->{$configcount}->{"name"}="vtcore.conf";
		$configs->{$configcount}->{"count"}=$os12;
		print "Created VTCore config file\n";
	}
	return(0);
} #}}}

sub proc_isdn()
{ #{{{
	my $port=0;
	my $conf;
	my $board=0;
	my $i;

	foreach my $cardnum (sort keys %{$cards}){
		if ($cards->{$cardnum}{"type"} eq "OPENPRI"){
			$board++;
			print("============= Card [$board] =============\n");
			#print Dumper($cards->{$cardnum});
			print(" Is this a single span [S|s], dual [D|d] or Logging [L|l]  card?:");
			my $ch = readline STDIN;
			my $bus = 0 + hex($cards->{$cardnum}{"bus"});
			my $slot = hex($cards->{$cardnum}{"dev"});

			if ($ch =~ /d/i ){
				printf(" [$board] is Dual span\n");
				$port++;
				$conf->{$port}->{"type"} = "";
				$conf->{$port}->{"CPU"}  = "A";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
				$port++;
				$conf->{$port}->{"type"} = "";
				$conf->{$port}->{"CPU"}  = "B";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
			}
			elsif ($ch =~ /l/i ){
				printf(" [$board] is Dual span logging card\n");
				$port++;
				$conf->{$port}->{"type"} = "logging";
				$conf->{$port}->{"CPU"}  = "A";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
				$port++;
				$conf->{$port}->{"type"} = "logging";
				$conf->{$port}->{"CPU"}  = "B";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
			}
			else {
				printf(" [$board] is Single span\n");
				$port++;
				$conf->{$port}->{"type"} = "";
				$conf->{$port}->{"CPU"}  = "A";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
			}
		} elsif ($cards->{$cardnum}{"type"} eq "OPENPRIv2"){
			$board++;
			print("============= Card [$board] =============\n");
			#print Dumper($cards->{$cardnum});
			print(" Is this a single span [S|s], dual [D|d] or Logging [L|l]  card?:");
			my $ch = readline STDIN;
			my $bus = 0 + hex($cards->{$cardnum}{"bus"});
			my $slot = hex($cards->{$cardnum}{"dev"});

			if ($ch =~ /d/i ){
				printf(" [$board] is Dual span\n");
				$port++;
				$conf->{$port}->{"type"} = "";
				$conf->{$port}->{"CPU"}  = "A";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
				$port++;
				$conf->{$port}->{"type"} = "";
				$conf->{$port}->{"CPU"}  = "B";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
			}
			elsif ($ch =~ /l/i ){
				printf(" [$board] is Dual span logging card\n");
				$port++;
				$conf->{$port}->{"type"} = "logging";
				$conf->{$port}->{"CPU"}  = "A";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
				$port++;
				$conf->{$port}->{"type"} = "logging";
				$conf->{$port}->{"CPU"}  = "B";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
			}
			else {
				printf(" [$board] is Single span\n");
				$port++;
				$conf->{$port}->{"type"} = "";
				$conf->{$port}->{"CPU"}  = "A";
				$conf->{$port}->{"card"} = "$board";
				$conf->{$port}->{"bus"}  = "$bus";
				$conf->{$port}->{"slot"} = "$slot";
			}
		}
	}
	if ($board == 0){
		print "There are no OpenPri cards to be configured.\n";
		return(0);
	}
	print("A total of $port ports will now be configured.\n");
	for ($i=1;$i<=$port;$i++){
		print("============= Port [$i] =============\n");
		print(" Is this port E1 or T1 ? [E|e|T|t](e):");
		my $ch = readline STDIN;
		if ($ch =~ /t/i ){
			printf(" port $i is T1/J1\n");
			$conf->{$i}->{"media"}="T1";
		}
		else {
			printf(" port $i is E1\n");
			$conf->{$i}->{"media"}="E1";
		}
		if ($conf->{$i}->{"type"} ne "logging"){
			print(" Is this port Client or Network? [C|c|N|n](c):");
			$ch = readline STDIN;
			if ($ch =~ /n/i ){
				printf(" port $i is Network\n");
				$conf->{$i}->{"clock"}="network";
			}
			else {
				printf(" port $i is Client\n");
				$conf->{$i}->{"clock"}="client";
			}
		}
		else {
			$conf->{$i}->{"clock"}="client";
			$conf->{$i+1}->{"media"}=$conf->{$i}->{"media"};
			$conf->{$i+1}->{"type"}=$conf->{$i}->{"type"};
			$conf->{$i+1}->{"clock"}="client";
			$i++;
		}
	}
	#print Dumper($conf);
	print("Making wanpipe config files now....\n");
	mkdir $priconfdir;
	open RC,">","$priconfdir/wanrouter.rc";
	print RC "#!/bin/sh\n";
	print RC "ROUTER_BOOT=YES\n";
	print RC "WAN_CONF_DIR=/etc/wanpipe\n";
	print RC "WAN_INTR_DIR=/etc/wanpipe/interfaces\n";
	print RC "WAN_LOG=/var/log/wanrouter\n";
	if ( -d '/var/lock/subsys' ) {
		print RC "WAN_LOCK=/var/lock/subsys/wanrouter\n";
		print RC "WAN_LOCK_DIR=/var/lock/subsys\n";
	} else {
		print RC "WAN_LOCK=/var/lock/wanrouter\n";
		print RC "WAN_LOCK_DIR=/var/lock\n";
	}
	print RC "WAN_IP_FORWARD=NO\n";
	print RC "NEW_IF_TYPE=NO\n";
	print RC "WAN_LIB_DIR=/etc/wanpipe/lib\n";
	print RC "WAN_ADSL_LIST=/etc/wanpipe/wan_adsl.list\n";
	print RC "WAN_ANNEXG_LOAD=NO\n";
	print RC "WAN_LIP_LOAD=YES\n";
	print RC "WAN_DYN_WANCONFIG=NO\n";
	print RC "WAN_SCRIPTS_DIR=/etc/wanpipe/scripts\n";
	print RC "WAN_FIRMWARE_DIR=/etc/wanpipe/firmware\n";
	print RC "WAN_DEVICES_REV_STOP_ORDER=YES\n";
	print RC "WAN_DEVICES=\"";

	my $channels=0;
	for ($i=1;$i<=$port;$i++){
		my $filename = "$priconfdir/wanpipe$i.conf";
		print RC "wanpipe$i ";
		open FH,">",$filename;
		print FH "[devices]\n";
		print FH "wanpipe$i = WAN_AFT, Comment\n\n";
		print FH "[interfaces]\n";
		if ($conf->{$i}->{"media"} eq "E1"){
			$channels = $channels + 30;
		} else {
			$channels = $channels + 23;
		}
		print FH "wp".$i."aft1 = wanpipe$i, auto, API, Comment\n";
		print FH "wp".$i."aft2 = wanpipe$i, auto, API, Comment\n";
		print FH "\n";
		print FH "[wanpipe$i]\n";
		print FH "CARD_TYPE         = AFT\n";
		print FH "S514CPU           = ".$conf->{$i}->{"CPU"}."\n";
		print FH "AUTO_PCISLOT      = NO\n";
		print FH "PCISLOT           = ".$conf->{$i}->{"slot"}."\n";
		print FH "PCIBUS            = ".$conf->{$i}->{"bus"}."\n";
		print FH "MEDIA             = ".$conf->{$i}->{"media"}."\n";
		print FH "TE_CLOCK          = NORMAL\n";
		if ($conf->{$i}->{"media"} eq "E1"){
			print FH "LCODE             = HDB3\n";
			print FH "FRAME             = CRC4\n";
		} else {
			print FH "LCODE             = B8ZS\n";
			print FH "FRAME             = ESF\n";
			print FH "TE_LBO            = 0DB\n";
		}
		print FH "ACTIVE_CH         = ALL\n";
		if ($conf->{$i}->{"clock"} eq "client"){
			print FH "Clocking          = External\n";
		} else {
			print FH "Clocking          = Internal\n";
		}
		print FH "Firmware          = /etc/wanpipe/firmware/cdual514.sfm\n";
		print FH "Interface         = V35\n";
		print FH "BaudRate          = 1540000\n";
		print FH "MTU               = 1500\n";
		print FH "UDPPORT           = 9000\n";
		print FH "TTL               = 255\n";
		print FH "IGNORE_FRONT_END  = NO\n";
		if ($conf->{$i}->{"type"} eq "logging"){
			print FH "TE_HIGHIMPEDANCE  = YES\n";
		}
		else {
			print FH "TE_HIGHIMPEDANCE  = NO\n";
		}
		print FH "\n";

		print FH "[wp".$i."aft1]\n";
		if ($conf->{$i}->{"media"} eq "E1"){
			print FH "ACTIVE_CH       = 1-15.17-31\n";
		} else {
			print FH "ACTIVE_CH       = 1-23\n";
		}
		print FH "HDLC_STREAMING  = NO\n";
		print FH "IDLE_FLAG       = 0x7E\n";
		if ($conf->{$i}->{"media"} eq "E1"){
			print FH "MTU             = 240\n";
			print FH "MRU             = 240\n";
		} else {
			print FH "MTU             = 184\n";
			print FH "MRU             = 184\n";
		}
		print FH "\n";

		print FH "[wp".$i."aft2]\n";
		if ($conf->{$i}->{"media"} eq "E1"){
			print FH "ACTIVE_CH       = 16\n";
		} else {
			print FH "ACTIVE_CH       = 24\n";
		}
		print FH "HDLC_STREAMING  = YES\n";
		print FH "\n";

		close FH;
		print "Done wanpipe".$i.".conf \n";
	}
	print RC "\"\n";
	close RC;
	print "Making openpri.conf config file now...\n";
	# check for logging cards
	my $logcount=0;
	for ($i=1;$i<=$port;$i++){
		if ($conf->{$i}->{"type"} eq "logging"){
			print "port $i is logging...\n";
			$logcount++;
			if ($conf->{$i}->{"media"} eq "E1"){
				$channels = $channels - (30/2);
			}
			else {
				$channels = $channels - (23/2);
			}
		}
	}
	my $cardcount = $port - ($logcount/2);
	mkdir $vpbconfdir;
	open FH,">","$vpbconfdir/openpri.conf";
	print FH "[general]\n";
	print FH "name=openpri\n";
	print FH "channels=$channels\n";
	print FH "cards=$cardcount\n\n";
	for ($i=0;$i<$port;$i++){
		$spans->{$spancount}="openpri:$spancount";
		my $idx=$i+1;
		print FH "[card$spancount]\n";
		$spancount++;
		print FH "priverbose=0\n";
		if($conf->{$idx}->{"type"} eq "logging"){
			print FH "name=wanpipe$idx,wanpipe".($idx+1)."\n";
		} else {
			print FH "name=wanpipe$idx\n";
		}
		print FH "iftype=".$conf->{$idx}->{"media"}."\n";
		if($conf->{$idx}->{"type"} eq "logging"){
			print FH "node=log\n";
		} else {
			print FH "node=".$conf->{$idx}->{"clock"}."\n";
		}
		if ($conf->{$idx}->{"media"} eq "E1"){
			print FH "protocol=euroisdn_e1\n";
		} else {
			print FH "protocol=ni2\n";
		}
		print FH "dialplan=unknown\n";
		print FH "localdialplan=unknown\n";
		if ($conf->{$idx}->{"media"} eq "E1"){
			print FH "dchannel=16\n";
			print FH "encoding=alaw\n";
		} else {
			print FH "dchannel=24\n";
			print FH "encoding=mulaw\n";
		}
		print FH "#playgain =\n";
		print FH "#recordgain =\n";
		if ($conf->{$idx}->{"media"} eq "E1"){
			for (my $x=1;$x<16;$x++){
				if($conf->{$idx}->{"type"} eq "logging"){
					print FH "channel$x=wp".$idx."aft1,wp".($idx+1)."aft1\n";
				} else {
					print FH "channel$x=wp".$idx."aft1\n";
				}
			}
			if($conf->{$idx}->{"type"} eq "logging"){
				print FH "channel16=wp".$idx."aft2,wp".($idx+1)."aft2\n";
			} else {
				print FH "channel16=wp".$idx."aft2\n";
			}
			for (my $x=17;$x<32;$x++){
				if($conf->{$idx}->{"type"} eq "logging"){
					print FH "channel$x=wp".$idx."aft1,wp".($idx+1)."aft1\n";
				} else {
					print FH "channel$x=wp".$idx."aft1\n";
				}
			}
		} else {
			if($conf->{$idx}->{"type"} eq "logging"){
				for (my $x=1;$x<24;$x++){
					print FH "channel$x=wp".$idx."aft1,wp".($idx+1)."aft1\n";
				}
				print FH "channel24=wp".$idx."aft2,wp".($idx+1)."aft2\n";
			} else {
				for (my $x=1;$x<24;$x++){
					print FH "channel$x=wp".$idx."aft1\n";
				}
				print FH "channel24=wp".$idx."aft2\n";
			}
		}
		print FH "\n";
		if($conf->{$idx}->{"type"} eq "logging"){
			$i++;
		}
	}
	$configcount++;
	$configs->{$configcount}->{"type"}="OPENPRI";
	$configs->{$configcount}->{"name"}="openpri.conf";
	$configs->{$configcount}->{"count"}=$port;
	print "Created OpenPRI config file\n";
	return(0);
} #}}}

sub proc_vpbconf()
{ #{{{
	print "Creating vpb.conf file...\n";

	mkdir $vpbconfdir;
	open FILE,">","$vpbconfdir/vpb.conf";
	print FILE "[general]\n";
	print FILE "name      = general\n";
	print FILE "verbosity = 0\n";
	print FILE "country   = $country_code\n";
	print FILE "\n";
	print FILE "[configs]\n";
	foreach my $idx (sort keys %{$configs}){
		if ($configs->{$idx}->{"type"} eq "V4PCI"){
			print FILE "openline = /etc/vpb/openline.conf\n";
		}
		elsif ($configs->{$idx}->{"type"} eq "V12PCI"){
			print FILE "openswitch = /etc/vpb/openswitch.conf\n";
		}
		elsif ($configs->{$idx}->{"type"} eq "OPENPRI"){
			print FILE "openpri = /etc/vpb/openpri.conf\n";
		}
		elsif ($configs->{$idx}->{"type"} eq "VTCORE"){
			print FILE "vtcore = /etc/vpb/vtcore.conf\n";
		}
	}
	print FILE "\n";
	print FILE "[cards]\n";
	foreach my $idx (sort keys %{$spans}){
		print FILE "$idx = ".$spans->{$idx}."\n";
	}
	close FILE;
} #}}}

