[dahdi-commits] tzafrir: tools/trunk r6013 - in /tools/trunk/xpp: ./ perl_modules/Dahdi/Confi...

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Fri Feb 13 15:09:51 CST 2009


Author: tzafrir
Date: Fri Feb 13 15:09:51 2009
New Revision: 6013

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6013
Log:
Rework dahdi_genconf to have separate configuration generation modules.

'dahdi_genconf foo bar' will use the modules Dahdi::Config::Gen::Foo and 
Dahdi::Config::Gen::Bar to generate configuraion files. Extra formats 
can thus be added without modifying dahdi_genconf and independently of
DAHDI.

Added:
    tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/
    tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm   (with props)
    tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm   (with props)
    tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/System.pm   (with props)
    tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Unicall.pm   (with props)
    tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Users.pm   (with props)
Modified:
    tools/trunk/xpp/dahdi_genconf

Modified: tools/trunk/xpp/dahdi_genconf
URL: http://svn.digium.com/svn-view/dahdi/tools/trunk/xpp/dahdi_genconf?view=diff&rev=6013&r1=6012&r2=6013
==============================================================================
--- tools/trunk/xpp/dahdi_genconf (original)
+++ tools/trunk/xpp/dahdi_genconf Fri Feb 13 15:09:51 2009
@@ -11,11 +11,12 @@
 use File::Basename;
 BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); }
 
+use Getopt::Std;
 use Dahdi;
-use Dahdi::Hardware;
 use Dahdi::Xpp;
 use Dahdi::Config::GenconfDefaults;
 
+my %opts;
 my $genconf_defaults;
 
 my %default_context = (
@@ -64,28 +65,35 @@
 	OUT	=> "fxo_{fxs_default_start}",
 	);
 
-my $file = '';
-my $base_exten = 4000;
-my $fxs_immediate = 'no';
 my $lc_country = 'us';
-my $loadzone = $lc_country;
-my $defaultzone = $lc_country;
-my $bri_sig_style = 'bri_ptmp';
-my $brint_overlap = 'no';
 my $pri_termtype = 'SPAN/* TE';
-my $pri_connection_type = 'PRI'; # PRI or R2
-my $r2_idle_bits = '1101';
 my $echo_can = 'mg2';
-my $bri_hardhdlc= 'no';
+
+my %global_config = (
+		'genconf_file'	=> 'HARD-CODED-DEFAULT',	# GenconfDefaults override
+		'base_exten'	=> 4000,
+		'fxs_immediate'	=> 'no',
+		'loadzone'	=> $lc_country,
+		'defaultzone'	=> $lc_country,
+		'context'	=> \%default_context,
+		'group'		=> \%default_group,
+		'bri_hardhdlc'	=> 'no',
+		'bri_sig_style'	=> 'bri_ptmp',
+		'r2_idle_bits'	=> '1101',
+		'bri_overlapdial'	=> 'no',
+		'pri_connection_type'	=> 'PRI', # PRI or R2
+		'dahdi_signalling'	=> \%default_dahdi_signalling,
+		'chan_dahdi_signalling'	=> \%default_chan_dahdi_signalling,
+	);
 
 my %dahdi_default_vars = (
-		GENCONF_FILE		=> \$file,
-		base_exten		=> \$base_exten,
-		fxs_immediate		=> \$fxs_immediate,
+		GENCONF_FILE		=> \$global_config{'genconf_file'},
+		base_exten		=> \$global_config{'base_exten'},
+		fxs_immediate		=> \$global_config{'fxs_immediate'},
 		fxs_default_start	=> \$fxs_default_start,
 		lc_country		=> [
-						\$loadzone,
-						\$defaultzone,
+						\$global_config{'loadzone'},
+						\$global_config{'defaultzone'},
 					],
 		context_lines		=> \$default_context{FXO},
 		context_phones		=> \$default_context{FXS},
@@ -97,13 +105,13 @@
 						\$default_group{OUT},
 					],
 		group_lines		=> \$default_group{FXO},
-		bri_sig_style		=> \$bri_sig_style,
-		brint_overlap		=> \$brint_overlap,
+		bri_sig_style		=> \$global_config{'bri_sig_style'},
+		bri_overlapdial		=> \$global_config{'bri_overlapdial'},
 		pri_termtype		=> \$pri_termtype,
-		pri_connection_type	=> \$pri_connection_type,
-		r2_idle_bits		=> \$r2_idle_bits,
+		pri_connection_type	=> \$global_config{'pri_connection_type'},
+		r2_idle_bits		=> \$global_config{'r2_idle_bits'},
 		echo_can		=> \$echo_can,
-		bri_hardhdlc		=> \$bri_hardhdlc,
+		bri_hardhdlc		=> \$global_config{'bri_hardhdlc'},
 		);
 
 sub map_dahdi_defaults {
@@ -130,603 +138,15 @@
 	}
 }
 
-
-my $dahdiconf_file;
-my $dahdimods_file;
-my $chan_dahdi_channels_file;
-my $users_file;
-my $asterisk_file;
-my $chan_dahdi_conf_file;
-my $unicall_channels_file;
-
-my %files = (
-	dahdi		=> { file => \$dahdiconf_file, func => \&gen_dahdiconf },
-	modules		=> { file => \$dahdimods_file, func => \&gen_dahdimods },
-	chan_dahdi	=> { file => \$chan_dahdi_channels_file, func => \&gen_chan_dahdi_channelsconf },
-	users		=> { file => \$users_file, func => \&gen_usersconf },
-	asterisk	=> { file => \$asterisk_file, func => \&gen_asterisk_conf },
-	unicall		=> { file => \$unicall_channels_file, func => \&gen_unicall_channels },
-	chan_dahdi_full	=> { file => \$chan_dahdi_conf_file, func => \&gen_chan_dahdi_conf },
-);
-
-my @default_files = ("dahdi", "chan_dahdi");
-
 my @spans = Dahdi::spans();
-
-sub bchan_range($) {
-	my $span = shift || die;
-	my $first_chan = ($span->chans())[0];
-	my $first_num = $first_chan->num();
-	my $range_start = $first_num;
-	my @range;
-	my $prev = undef;
-
-	die unless $span->is_digital();
-	foreach my $c (@{$span->bchan_list()}) {
-		my $curr = $c + $first_num;
-		if(!defined($prev)) {
-			$prev = $curr;
-		} elsif($curr != $prev + 1) {
-			push(@range, sprintf("%d-%d", $range_start, $prev));
-			$range_start = $curr;
-		}
-		$prev = $curr;
-	}
-	if($prev >= $first_num) {
-		push(@range, sprintf("%d-%d", $range_start, $prev));
-	}
-	return join(',', @range);
-}
-
-sub gen_dahdi_signalling($) {
-	my $chan = shift || die;
-	my $type = $chan->type;
-	my $num = $chan->num;
-
-	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
-	if($type eq 'EMPTY') {
-		printf "# channel %d, %s, no module.\n", $num, $chan->fqn;
-		return;
-	}
-	my $sig = $default_dahdi_signalling{$type} || die "unknown default dahdi signalling for chan $num type $type";
-	if ($type eq 'IN') {
-		printf "# astbanktype: input\n";
-	} elsif ($type eq 'OUT') {
-		printf "# astbanktype: output\n";
-	}
-	printf "$sig=$num\n";
-	print_echo_can($num);
-}
-
-sub print_echo_can($) {
-	my $chans = shift; # channel or range of channels.
-	return if ($echo_can eq 'none');
-
-	print "echocanceller=$echo_can,$chans\n";
-}
-
-my $bri_te_last_timing = 1;
-
-sub gen_dahdi_digital($) {
-	my $span = shift || die;
-	my $num = $span->num() || die;
-	die "Span #$num is analog" unless $span->is_digital();
-	my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
-	my $timing;
-	my $lbo = 0;
-	my $framing = $span->framing() || die "$0: No framing information for span #$num\n";
-	my $coding =  $span->coding() || die "$0: No coding information for span #$num\n";
-	my $span_crc4 = $span->crc4();
-	$span_crc4 = (defined $span_crc4) ? ",$span_crc4" : '';
-	my $span_yellow = $span->yellow();
-	$span_yellow = (defined $span_yellow) ? ",$span_yellow" : '';
-	# "MFC/R2 does not normally use CRC4"
-	# FIXME: a finer way to override:
-	if ($pri_connection_type eq 'R2') { 
-		$span_crc4 = '';
-		$framing = 'cas';
-	}
-	my $dchan_type = 'dchan';
-	if ($span->is_bri() && ($bri_hardhdlc eq 'yes')) {
-		$dchan_type = 'hardhdlc';
-	}
-
-	$timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++;
-	printf "span=%d,%d,%d,%s,%s%s%s\n",
-			$num,
-			$timing,
-			$lbo,
-			$framing,
-			$coding,
-			$span_crc4,
-			$span_yellow;
-	printf "# termtype: %s\n", lc($termtype);
-	if ($pri_connection_type eq 'PRI') {
-		printf "bchan=%s\n", bchan_range($span);
-		my $dchan = $span->dchan();
-		printf "$dchan_type=%d\n", $dchan->num();
-	} elsif ($pri_connection_type eq 'R2' ) {
-		my $idle_bits = $r2_idle_bits; 
-		printf "cas=%s:$idle_bits\n", bchan_range($span);
-		printf "dchan=%d\n", $span->dchan()->num();
-	}
-	print_echo_can(bchan_range($span));
-}
-
-sub gen_unicall_channels($) {
-	my $file = shift || die;
-	die "Only for R2" unless $pri_connection_type eq 'R2';
-	rename "$file", "$file.bak"
-		or $! == 2	# ENOENT (No dependency on Errno.pm)
-		or die "Failed to backup old config: $!\n";
-	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-	printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
-	print  "; This file should be #included in unicall.conf\n\n";
-	foreach my $span (@spans) {
-		next unless $span->is_digital();
-		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
-		my $idle_bits = $r2_idle_bits; 
-		printf "protocolend=%s\n", ($span->termtype() eq 'TE') ? 'cpe' : 'co';
-		printf "channel=%s\n", bchan_range($span);
-		print "\n";
-	}
-	close F;
-	select $old;
-}
-
-
-sub gen_dahdiconf($) {
-	my $file = shift || die;
-	rename "$file", "$file.bak"
-		or $! == 2	# ENOENT (No dependency on Errno.pm)
-		or die "Failed to backup old config: $!\n";
-	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-	printf "# Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
-	print <<"HEAD";
-# Dahdi Configuration File
-#
-# This file is parsed by the Dahdi Configurator, dahdi_cfg
-#
-HEAD
-	foreach my $span (@spans) {
-		printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description;
-		if($span->is_digital()) {
-			gen_dahdi_digital($span);
-		} else {
-			foreach my $chan ($span->chans()) {
-				if(1 || !defined $chan->type) {
-					my $type = $chan->probe_type;
-					my $num = $chan->num;
-					die "Failed probing type for channel $num"
-						unless defined $type;
-					$chan->type($type);
-				}
-				gen_dahdi_signalling($chan);
-			}
-		}
-		print "\n";
-	}
-	print <<"TAIL";
-# Global data
-
-loadzone	= $loadzone
-defaultzone	= $defaultzone
-TAIL
-	close F;
-	select $old;
-}
-
-
-sub gen_dahdimods($) {
-	my $file = shift || die;
-	rename "$file", "$file.bak"
-		or $! == 2	# ENOENT (No dependency on Errno.pm)
-		or die "Failed to backup old config: $!\n";
-	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-	printf "# Autogenerated by %s on %s\n", $0, scalar(localtime);
-	print <<"HEAD";
-# List of modules for DAHDI devices detected on the system
-#
-# This file is parsed by the dahdi init.d script, /etc/init.d/dahdi
-# Anything after '#' is a comment. List one module in a line.
-#
-HEAD
-	my $hardware = Dahdi::Hardware->scan;
-	foreach my $dev ($hardware->device_list) {
-		my $description = $dev->description || "";
-		printf "%s\t#%s %s\n", $dev->driver,
-			$dev->description, $dev->hardware_name;
-	}
-	close F;
-	select $old;
-}
-
-my %DefaultConfigs = (
-	context => 'default',
-	group => '63', # FIXME: should not be needed. 
-	overlapdial => 'no',
-	busydetect => 'no',
-	rxgain => 0,
-	txgain => 0,
-);
-
-sub reset_chan_dahdi_values {
-	foreach my $arg (@_) {
-		if (exists ($DefaultConfigs{$arg})) {
-			print "$arg = $DefaultConfigs{$arg}\n";
-		} else {
-			print "$arg =\n";
-		}
-	}
-}
-
-sub gen_chan_dahdi_digital($) {
-	my $span = shift || die;
-	my $num = $span->num() || die;
-	die "Span #$num is analog" unless $span->is_digital();
-	if($span->is_pri && $pri_connection_type eq 'R2') {
-		printf "; Skipped: $pri_connection_type config generated into $unicall_channels_file\n\n";
-		return;
-	}
-	my $type = $span->type() || die "$0: Span #$num -- unkown type\n";
-	my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
-	my $group = $default_group{"$type"};
-	my $context = $default_context{"$type"};
-	my @to_reset = qw/context group/;
-
-	die "$0: missing default group (termtype=$termtype)\n" unless defined($group);
-	die "$0: missing default context\n" unless $context;
-
-	my $sig = $span->signalling || die "missing signalling info for span #$num type $type";
-	grep($bri_sig_style eq $_, 'bri', 'bri_ptmp', 'pri') or die "unknown signalling style for BRI";
-	if($span->is_bri() and $bri_sig_style eq 'bri_ptmp') {
-		$sig .= '_ptmp';
-	}
-	if ($span->is_bri() && $termtype eq 'NT' && $brint_overlap eq 'yes') {
-		print "overlapdial = yes\n";
-		push(@to_reset, qw/overlapdial/);
-	}
-		
-	$group .= "," . (10 + $num);	# Invent unique group per span
-	printf "group=$group\n";
-	printf "context=$context\n";
-	printf "switchtype = %s\n", $span->switchtype;
-	printf "signalling = %s\n", $sig;
-	printf "channel => %s\n", bchan_range($span);
-	reset_chan_dahdi_values(@to_reset);
-}
-
-sub gen_chan_dahdi_channel($) {
-	my $chan = shift || die;
-	my $type = $chan->type;
-	my $num = $chan->num;
-	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
-	my $exten = $base_exten + $num;
-	my $sig = $default_chan_dahdi_signalling{$type};
-	my $context = $default_context{$type};
-	my $group = $default_group{$type};
-	my $callerid;
-	my $immediate;
-
-	return if $type eq 'EMPTY';
-	die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig;
-	$callerid = ($type eq 'FXO')
-			? 'asreceived'
-			: sprintf "\"Channel %d\" <%04d>", $num, $exten;
-	if($type eq 'IN') {
-		$immediate = 'yes';
-	}
-	# FIXME: $immediage should not be set for 'OUT' channels, but meanwhile
-	#        it's better to be compatible with genzaptelconf
-	$immediate = 'yes' if $fxs_immediate eq 'yes' and $sig =~ /^fxo_/;
-	my $signalling = $chan->signalling;
-	$signalling = " " . $signalling if $signalling;
-	my $info = $chan->info;
-	$info = " " . $info if $info;
-	printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info;
-	printf "signalling=$sig\n";
-	printf "callerid=$callerid\n";
-	printf "mailbox=%04d\n", $exten unless $type eq 'FXO';
-	if(defined $group) {
-		printf "group=$group\n";
-	}
-	printf "context=$context\n";
-	printf "immediate=$immediate\n" if defined $immediate;
-	printf "channel => %d\n", $num;
-	# Reset following values to default
-	printf "callerid=\n";
-	printf "mailbox=\n" unless $type eq 'FXO';
-	if(defined $group) {
-		printf "group=\n";
-	}
-	printf "context=default\n";
-	printf "immediate=no\n" if defined $immediate;
-	print "\n";
-}
-
-sub gen_chan_dahdi_channelsconf($) {
-	my $file = shift || die;
-	rename "$file", "$file.bak"
-		or $! == 2	# ENOENT (No dependency on Errno.pm)
-		or die "Failed to backup old config: $!\n";
-	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-	printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
-	print <<"HEAD";
-; Dahdi Channels Configurations (chan_dahdi.conf)
-;
-; This is not intended to be a complete chan_dahdi.conf. Rather, it is intended
-; to be #include-d by /etc/asterisk/chan_dahdi.conf that will include the global settings
-;
-
-HEAD
-	foreach my $span (@spans) {
-		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
-		if($span->is_digital()) {
-			gen_chan_dahdi_digital($span);
-		} else {
-			foreach my $chan ($span->chans()) {
-				gen_chan_dahdi_channel($chan);
-			}
-		}
-		print "\n";
-	}
-	close F;
-	select $old;
-}
-
-sub gen_users_channel($) {
-	my $chan = shift || die;
-	my $type = $chan->type;
-	my $num = $chan->num;
-	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
-	my $exten = $base_exten + $num;
-	my $sig = $default_chan_dahdi_signalling{$type};
-	my $full_name = "$type $num";
-
-	die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig;
-	print << "EOF";
-[$exten]
-callwaiting = yes
-context = numberplan-custom-1
-fullname = $full_name
-cid_number = $exten
-hasagent = no
-hasdirectory = no
-hasiax = no
-hasmanager = no
-hassip = no
-hasvoicemail = yes
-host = dynamic
-mailbox = $exten
-threewaycalling = yes
-vmsecret = 1234
-secret = 1234
-signalling = $sig
-dahdichan = $num
-registeriax = no
-registersip = no
-canreinvite = no
-nat = no
-dtmfmode = rfc2833
-disallow = all
-allow = all
-
-EOF
-}
-
-# Shifts standard output to a file (which is actually the global 'F').
-# Saves original file as a backup.
-# Input: name of file. If it is '-', no action is taken.
-sub stdout_to_file($) {
-	my $file = shift || die;
-	return '-' if ($file eq '-');
-
-	rename "$file", "$file.bak"
-		or $! == 2	# ENOENT (No dependency on Errno.pm)
-		or die "Failed to backup old config: $!\n";
-	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-
-	return $old;
-}
-
-# Shifts standard output back to the original (unless the input file 
-# was '-', in which case no action is needed).
-# Input: the original file descriptor, as returned from stdout_to_file().
-sub stdout_restore($) {
-	my $old = shift || die;
-	return '-' if ($old eq '-');
-
-	close F;
-	select $old;
-}
-
-
-# Provide information for VoiceRoute's Druid Zaptel wizard
-sub gen_asterisk_conf($) {
-	my $file = shift || die;
-	my $old = stdout_to_file($file);
-
-	print << "EOF";
-; The following provides information about DAHDI hardware, spans and 
-; channels, in the format parsable to an Asterisk configuration file
-; parser.
-;
-; THE FORMAT IS SUBJECT TO CHANGES
-EOF
-	my $hardware = Dahdi::Hardware->scan;
-	foreach my $dev ($hardware->device_list) {
-		$dev->{ASTERISK_NAME} = "dev-".$dev->hardware_name;
-		print "[".$dev->asterisk_name."]\n";
-		printf "vendor = %s\n", $dev->vendor;
-		printf "product = %s\n", $dev->product;
-		printf "description = %s\n", $dev->description;
-		printf "hardware_name = %s\n", $dev->hardware_name;
-		printf "driver = %s\n", $dev->driver;
-		# TODO: indicate if driver != loaded?
-		printf "loaded = %s\n", $dev->loaded;
-		print "\n";
-	}
-
-	foreach my $span (@spans) {
-		$span->{ASTERISK_NAME} = "span-".$span->num;
-		print "[".$span->asterisk_name."]\n";
-		#next unless grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' );
-		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
-		printf "num = %s\n", $span->num;
-		printf "type = %s\n", $span->type;
-		printf "name = %s\n", $span->name;
-		printf "description = %s\n", $span->description;
-		printf "digital = %s\n", 
-			$span->is_digital? 'yes' : 'no';
-
-		if ($span->is_digital) {
-			printf "switchtype = %s\n", $span->switchtype;
-			printf "signalling = %s\n", $span->signalling;
-			printf "channels = %s\n", bchan_range($span);
-			print "\n";
-		} else {
-			print "\n";
-			foreach my $chan ($span->chans()) {
-				my $type = $chan->type;
-				my $sig = $default_dahdi_signalling{$type};
-				$chan->{ASTERISK_NAME} = "chan-".$chan->num;
-
-				print "[".$chan->asterisk_name."]\n";
-
-				printf "type = %s\n", $type;
-				printf "span = %s\n", $chan->span->asterisk_name;
-				printf "channels = %s\n", $chan->num;
-				printf "index = %s\n", $chan->index;
-				printf "name = %s\n", $chan->fqn;
-				printf "signalling = %s\n", $sig;
-				print "\n";
-			}
-		}
-	}
-
-	stdout_restore($old);
-}
-
-
-# generate users.conf . The specific users.conf is strictly oriented
-# towards using with the asterisk-gui .
-#
-# This code could have generated a much simpler and smaller
-# configuration file, had there been minimal level of support for
-# configuration templates in the asterisk configuration rewriting. Right
-# now Asterisk's configuration rewriting simply freaks out in the face
-# of templates: http://bugs.digium.com/11442 .
-sub gen_usersconf($) {
-	my $file = shift || die;
-	rename "$file", "$file.bak"
-		or $! == 2	# ENOENT (No dependency on Errno.pm)
-		or die "Failed to backup old config: $!\n";
-	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-	print <<"HEAD";
-;!
-;! Automatically generated configuration file
-;! Filename: @{[basename($file)]} ($file)
-;! Generator: $0
-;! Creation Date: @{[scalar(localtime)]}
-;!
-[general]
-;
-; Full name of a user
-;
-fullname = New User
-;
-; Starting point of allocation of extensions
-;
-userbase = @{[$base_exten+1]}
-;
-; Create voicemail mailbox and use use macro-stdexten
-;
-hasvoicemail = yes
-;
-; Set voicemail mailbox @{[$base_exten+1]} password to 1234
-;
-vmsecret = 1234
-;
-; Create SIP Peer
-;
-hassip = no
-;
-; Create IAX friend
-;
-hasiax = no
-;
-; Create Agent friend
-;
-hasagent = no
-;
-; Create H.323 friend
-;
-;hash323 = yes
-;
-; Create manager entry
-;
-hasmanager = no
-;
-; Remaining options are not specific to users.conf entries but are general.
-;
-callwaiting = yes
-threewaycalling = yes
-callwaitingcallerid = yes
-transfer = yes
-canpark = yes
-cancallforward = yes
-callreturn = yes
-callgroup = 1
-pickupgroup = 1
-localextenlength = @{[length($base_exten)]}
-
-
-HEAD
-	foreach my $span (@spans) {
-		next unless grep { $_ eq $span->type} ( 'FXS', 'IN', 'OUT' );
-		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
-		foreach my $chan ($span->chans()) {
-			gen_users_channel($chan);
-		}
-		print "\n";
-	}
-	close F;
-	select $old;
-}
-
-sub gen_chan_dahdi_conf($) {
-	my $file = shift || die;
-	open(F, ">>$file") || die "$0: Failed to open $file: $!\n";
-	my $old = select F;
-	foreach my $span (@spans) {
-		next unless $span->type eq 'FXO';
-		my $current_sig = "";
-		for my $chan ($span->chans()) {
-			my $chan_num = $chan->num;
-			if ($default_chan_dahdi_signalling{$chan->type} ne $current_sig) {
-				$current_sig = $default_chan_dahdi_signalling{$chan->type};
-				print "\nsignalling = $current_sig";
-				print "\nchannel => $chan_num";
-			} else {
-				print ",$chan_num";
-			}
-		}
-		print "\n";
-	}
-	close F;
-	select $old;
-}
 
 sub set_defaults {
 	# Source default files
 	my $default_file = $ENV{GENCONF_PARAMETERS} || "/etc/dahdi/genconf_parameters";
 	$genconf_defaults = Dahdi::Config::GenconfDefaults->new($default_file);
+	if($opts{v}) {
+		print "Default parameters from ", $genconf_defaults->{GENCONF_FILE}, "\n";
+	}
 	#$genconf_defaults->dump;
 	map_dahdi_defaults(%$genconf_defaults);
 	foreach my $span (@spans) {
@@ -738,39 +158,69 @@
 	foreach my $val (values %default_dahdi_signalling, values %default_chan_dahdi_signalling) {
 		$val =~ s/{fxs_default_start}/$fxs_default_start/g;
 	}
-	$dahdiconf_file = $ENV{DAHDI_CONF_FILE} || "/etc/dahdi/system.conf";
-	$dahdimods_file = $ENV{DAHDI_MODS_FILE} || "/etc/dahdi/modules";
-	$chan_dahdi_channels_file = $ENV{CHAN_DAHDI_CHANNELS_FILE} || "/etc/asterisk/dahdi-channels.conf";
-	$users_file = $ENV{USERS_FILE} || "/etc/asterisk/users.conf";
-	$asterisk_file = $ENV{ASTERISK_FILE} || 
-		"/var/lib/asterisk/asterisk-detect-hardware.conf";
-	$unicall_channels_file = $ENV{UNICALL_CHANNELS_FILE} || "/etc/asterisk/unicall-channels.conf";
-	$chan_dahdi_conf_file = $ENV{CHAN_DAHDI_CONF_FILE} || "/etc/asterisk/chan_dahdi.conf";
 }
 
 sub parse_args {
-	if (not @ARGV) {
+	my @default_generators;
+
+	getopts('v', \%opts);
+	if (@ARGV) {
+		for my $gen (@ARGV) {
+			push @default_generators, $gen;
+		}
+	} else {
 		# No files given. Use the defaults.
-		push(@ARGV, 'unicall') if $pri_connection_type eq 'R2';
-		return;
-	}
-
-	@default_files = ();
-	for my $file (@ARGV) {
-		die "$0: Unknown file '$file'" unless defined $files{$file};
-		push @default_files, $file;
-	}
-}
-
-sub generate_files {
-	for my $file (@default_files) {
-		&{$files{$file}->{func}}(${$files{$file}->{file}});
-	}
-}
-
+		@default_generators = ('system', 'chandahdi');
+		if($global_config{'pri_connection_type'} eq 'R2') {
+			push @default_generators, 'unicall';
+		}
+	}
+	return @default_generators;
+}
+
+sub run_generator($$) {
+	my ($name, $genopts) = @_;
+
+	if(defined $opts{'v'}) {
+		$genopts->{'verbose'} = $opts{v};
+	}
+	my $module = "Dahdi::Config::Gen::$name";
+	eval "use $module";
+	if($@) {
+		die "Failed to load configuration generator for '$name'\n";
+	}
+	my $cfg = new $module(\%global_config, $genopts);
+	$cfg->generate(@spans);
+}
+
+sub parse_genopts($) {
+	my $optstr = shift;
+	my %genopts;
+
+	$optstr = '' unless defined $optstr;
+	foreach my $o (split(/,/, $optstr)) {
+		my ($k, $v) = split(/=/, $o, 2);
+		$v = 1 unless defined $v and $v;
+		$genopts{$k} = $v;
+	}
+	return %genopts;
+}
+
+sub generate_files(@) {
+	my @default_generators = @_;
+
+	for my $gen (@default_generators) {
+		my ($name, $optstr) = split(/=/, $gen, 2);
+		die "Illegal name '$name'\n" unless $name =~ /^\w+$/;
+		$name =~ s/(.)(.*)/\u$1\L$2/;
+		my %genopts = parse_genopts($optstr);
+		run_generator($name, \%genopts);
+	}
+}
+
+my @default_generators = parse_args;
 set_defaults;
-parse_args;
-generate_files;
+generate_files @default_generators;
 
 __END__
 
@@ -780,62 +230,47 @@
 
 =head1 SYNOPSIS
 
-dahdi_genconf [FILES...]
+dahdi_genconf [options] [generator...]
 
 =head1 DESCRIPTION
 
-This script generate configuration files for DAHDI hardware. The
-parameters are types of files to generate. By default it will generate
-the types 'dahdi' and 'chan_dahdi'. See below a complete list.
+This script generate configuration files for Dahdi hardware.
+It uses two information sources:
 
 =over 4
 
-=item dahdi - /etc/dahdi/system.conf
-
-Configuration for dahdi_cfg(1). Its location may be overriden by the
-environment variable DAHDI_CONF_FILE.
-
-=item modules /etc/dahdi/modules
-
-List of DAHDI kernel modules to be loaded by the init.d script. One
-module per line. Its location may be overriden with the variable
-DAHDI_MODS_FILE.
-
-=item chan_dahdi - /etc/asterisk/dahdi-channels.conf
-
-Configuration for asterisk(1). It should be included in the main /etc/asterisk/chan_dahdi.conf.
-Its location may be overriden by the environment variable 
-CHAN_DAHDI_CHANNELS_FILE.
-
-=item users - /etc/asterisk/users.conf
-
-Configuration for asterisk(1) and AsteriskGUI.
-Its location may be overriden by the environment variable USERS_FILE.
-
-=item asterisk - /var/lib/asterisk/asterisk-detected-zap.conf
-
-Dump information (hardware, spans and channels) in the format of an 
-Asterisk configuration file.
-
-=item chan_dahdi_full - /etc/asterisk/chan_dahdi.conf
-
-Configuration for asterisk(1) and AsteriskGUI.
-Its location may be overriden by the environment variable CHAN_DAHDI_CONF_FILE.
+=item Hardware
+
+ The actual dahdi hardware is automatically detected on the host.
+
+=item /etc/dahdi/genconf_params
+
+A configuration file that supplements the hardware information.
+Its location may be overriden via the C<GENCONF_PARAMETERS> environment
+variable.
 
 =back
 
-=head1 EXAMPLES
-
-Generate /etc/dahdi/system.conf ('dahdi') and a snippet of
-chan_dahdi.conf ('chan_dahdi'):
-
-  dahdi_genconf
-
-Create those two files, and /etc/dahdi/modules:
-
-  dahdi_genconf chan_dahdi dahdi modules
-
-Print Asterisk configuration-file formatted report to the standard
-output:
-
-  ASTERISK_FILE=- dahdi_conf asterisk
+The dahdi_genconf script can generate various kinds of configuration files
+as specificed by the generator arguments.  Each generator is a perl classes
+in Dahdi::Config::Gen namespace.  The generator names on the command line
+are the class names in lowercase.
+
+The following generators are currently implemented: system, chandahdi, unicall, users.
+For further documentation on each, please user perldoc on the relevant
+class. E.g: C<perldoc Dahdi::Config::Gen::Chandahdi>
+
+Each generator on the command line may be passed custom options by assigning
+a comma separated list of options to the generator name. E.g:
+
+ dahdi_genconf system chandahdi=verbose unicall
+
+Global options:
+
+=over 4
+
+=item -v
+
+Verbose -- also sets the C<'verbose'> option for all generators.
+
+=back

Added: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm
URL: http://svn.digium.com/svn-view/dahdi/tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm?view=auto&rev=6013
==============================================================================
--- tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm (added)
+++ tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm Fri Feb 13 15:09:51 2009
@@ -1,0 +1,48 @@
+package Dahdi::Config::Gen;
+require Exporter;
+ at ISA = qw(Exporter);
+
+ at EXPORT_OK = qw(is_true);
+
+use strict;
+
+sub is_true($) {
+	my $val = shift || die;
+	return $val =~ /^(1|y|yes)$/i;
+}
+
+sub show_gconfig($) {
+	my $gconfig = shift || die;
+
+	print "Global configuration:\n";
+	foreach my $key (sort keys %{$gconfig}) {
+		printf "  %-20s %s\n", $key, $gconfig->{$key};
+	}
+}
+
+sub bchan_range($) {
+	my $span = shift || die;
+	my $first_chan = ($span->chans())[0];
+	my $first_num = $first_chan->num();
+	my $range_start = $first_num;
+	my @range;
+	my $prev = undef;
+
+	die unless $span->is_digital();
+	foreach my $c (@{$span->bchan_list()}) {
+		my $curr = $c + $first_num;
+		if(!defined($prev)) {
+			$prev = $curr;
+		} elsif($curr != $prev + 1) {
+			push(@range, sprintf("%d-%d", $range_start, $prev));
+			$range_start = $curr;
+		}
+		$prev = $curr;
+	}
+	if($prev >= $first_num) {
+		push(@range, sprintf("%d-%d", $range_start, $prev));
+	}
+	return join(',', @range);
+}
+
+1;

Propchange: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen.pm
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
URL: http://svn.digium.com/svn-view/dahdi/tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm?view=auto&rev=6013
==============================================================================
--- tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm (added)
+++ tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm Fri Feb 13 15:09:51 2009
@@ -1,0 +1,210 @@
+package Dahdi::Config::Gen::Chandahdi;
+use strict;
+
+use Dahdi::Config::Gen qw(is_true);
+
+sub new($$$) {
+	my $pack = shift || die;
+	my $gconfig = shift || die;
+	my $genopts = shift || die;
+	my $file = $ENV{CHAN_DAHDI_CHANNELS_FILE} || "/etc/asterisk/dahdi-channels.conf";
+	my $self = {
+			FILE	=> $file,
+			GCONFIG	=> $gconfig,
+			GENOPTS	=> $genopts,
+		};
+	bless $self, $pack;
+	return $self;
+}
+
+# Since chan_dahdi definitions "leak" to the next ones, we try
+# To reset some important definitions to their chan_dahdi defaults.
+my %chan_dahdi_defaults = (
+	context => 'default',
+	group => '63', # FIXME: should not be needed. 
+	overlapdial => 'no',
+	busydetect => 'no',
+	rxgain => 0,
+	txgain => 0,
+);
+
+sub reset_chandahdi_values {
+	foreach my $arg (@_) {
+		if (exists $chan_dahdi_defaults{$arg}) {
+			print "$arg = $chan_dahdi_defaults{$arg}\n";
+		} else {
+			print "$arg =\n";
+		}
+	}
+}
+
+sub gen_digital($$) {
+	my $self = shift || die;
+	my $span = shift || die;
+	my $gconfig = $self->{GCONFIG};
+	my $num = $span->num() || die;
+	die "Span #$num is analog" unless $span->is_digital();
+	if($span->is_pri && $gconfig->{'pri_connection_type'} eq 'R2') {
+		printf "; Skipped: $gconfig->{'pri_connection_type'}\n\n";
+		return;
+	}
+	my $type = $span->type() || die "$0: Span #$num -- unkown type\n";
+	my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
+	my $group = $gconfig->{'group'}{"$type"};
+	my $context = $gconfig->{'context'}{"$type"};
+	my @to_reset = qw/context group/;
+
+	die "$0: missing default group (termtype=$termtype)\n" unless defined($group);
+	die "$0: missing default context\n" unless $context;
+
+	my $sig = $span->signalling || die "missing signalling info for span #$num type $type";
+	grep($gconfig->{'bri_sig_style'} eq $_, 'bri', 'bri_ptmp', 'pri') or die "unknown signalling style for BRI";
+	if($span->is_bri() and $gconfig->{'bri_sig_style'} eq 'bri_ptmp') {
+		$sig .= '_ptmp';
+	}
+	if ($span->is_bri() && $termtype eq 'NT' && is_true($gconfig->{'brint_overlap'})) {
+		print "overlapdial = yes\n";
+		push(@to_reset, qw/overlapdial/);
+	}
+		
+	$group .= "," . (10 + $num);	# Invent unique group per span
+	printf "group=$group\n";
+	printf "context=$context\n";
+	printf "switchtype = %s\n", $span->switchtype;
+	printf "signalling = %s\n", $sig;
+	printf "channel => %s\n", Dahdi::Config::Gen::bchan_range($span);
+	reset_chandahdi_values(@to_reset);
+}
+
+sub gen_channel($$) {
+	my $self = shift || die;
+	my $chan = shift || die;
+	my $gconfig = $self->{GCONFIG};
+	my $type = $chan->type;
+	my $num = $chan->num;
+	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
+	my $exten = $gconfig->{'base_exten'} + $num;
+	my $sig = $gconfig->{'chan_dahdi_signalling'}{$type};
+	my $context = $gconfig->{'context'}{$type};
+	my $group = $gconfig->{'group'}{$type};
+	my $callerid;
+	my $immediate;
+
+	return if $type eq 'EMPTY';
+	die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig;
+	$callerid = ($type eq 'FXO')
+			? 'asreceived'
+			: sprintf "\"Channel %d\" <%04d>", $num, $exten;
+	if($type eq 'IN') {
+		$immediate = 'yes';
+	}
+	# FIXME: $immediage should not be set for 'OUT' channels, but meanwhile
+	#        it's better to be compatible with genzaptelconf
+	$immediate = 'yes' if $gconfig->{'fxs_immediate'} eq 'yes' and $sig =~ /^fxo_/;
+	my $signalling = $chan->signalling;
+	$signalling = " " . $signalling if $signalling;
+	my $info = $chan->info;
+	$info = " " . $info if $info;
+	printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info;
+	printf "signalling=$sig\n";
+	printf "callerid=$callerid\n";
+	printf "mailbox=%04d\n", $exten unless $type eq 'FXO';
+	if(defined $group) {
+		printf "group=$group\n";
+	}
+	printf "context=$context\n";
+	printf "immediate=$immediate\n" if defined $immediate;
+	printf "channel => %d\n", $num;
+	# Reset following values to default
+	printf "callerid=\n";
+	printf "mailbox=\n" unless $type eq 'FXO';
+	if(defined $group) {
+		printf "group=\n";
+	}
+	printf "context=default\n";
+	printf "immediate=no\n" if defined $immediate;
+	print "\n";
+}
+
+sub generate($) {
+	my $self = shift || die;
+	my $file = $self->{FILE};
+	my $gconfig = $self->{GCONFIG};
+	my $genopts = $self->{GENOPTS};
+	#Dahdi::Config::Gen::show_gconfig($gconfig);
+	my @spans = @_;
+	warn "Empty configuration -- no spans\n" unless @spans;
+	rename "$file", "$file.bak"
+		or $! == 2	# ENOENT (No dependency on Errno.pm)
+		or die "Failed to backup old config: $!\n";
+	print "Generating $file\n" if $genopts->{verbose};
+	open(F, ">$file") || die "$0: Failed to open $file: $!\n";
+	my $old = select F;
+	printf "; Autogenerated by %s on %s -- do not hand edit\n", $0, scalar(localtime);
+	print <<"HEAD";
+; Dahdi Channels Configurations (chan_dahdi.conf)
+;
+; This is not intended to be a complete chan_dahdi.conf. Rather, it is intended
+; to be #include-d by /etc/chan_dahdi.conf that will include the global settings
+;
+
+HEAD
+	foreach my $span (@spans) {
+		printf "; Span %d: %s %s\n", $span->num, $span->name, $span->description;
+		if($span->is_digital()) {
+			$self->gen_digital($span);
+		} else {
+			foreach my $chan ($span->chans()) {
+				if($genopts->{'freepbx'}) {
+					# Freepbx has its own idea about channels
+					my $type = $chan->type;
+					if($type eq 'FXS' || $type eq 'OUT' || $type eq 'IN') {
+						printf "; Skip channel=%s($type) -- freepbx option.\n",
+							$chan->num;
+						next;
+					}
+				}
+				$self->gen_channel($chan);
+			}
+		}
+		print "\n";
+	}
+	close F;
+	select $old;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+chandahdi - Generate configuration for chan_dahdi channels.
+
+=head1 SYNOPSIS
+
+ use Dahdi::Config::Gen::Chandahdi;
+
+ my $cfg = new Dahdi::Config::Gen::Chandahdi(\%global_config, \%genopts);
+ $cfg->generate(@span_list);
+
+=head1 DESCRIPTION
+
+Generate the F</etc/asterisk/dahdi-channels.conf>
+This is used as a configuration for asterisk(1).
+It should be included in the main F</etc/asterisk/chan_dahdi.conf>.
+
+Its location may be overriden via the environment variable 
+C<CHAN_DAHDI_CHANNELS_FILE>.
+
+=head1 OPTIONS
+
+=over 4
+
+=item freepbx
+
+With this option we do not generate channel definitions for FXS, Input and
+Output ports. This is done because these channel definitions need to be
+generated and inserted into I<freepbx> database anyway.
+
+=back

Propchange: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/System.pm
URL: http://svn.digium.com/svn-view/dahdi/tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/System.pm?view=auto&rev=6013
==============================================================================
--- tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/System.pm (added)
+++ tools/trunk/xpp/perl_modules/Dahdi/Config/Gen/System.pm Fri Feb 13 15:09:51 2009
@@ -1,0 +1,158 @@
+package Dahdi::Config::Gen::System;
+use strict;
+
+use Dahdi::Config::Gen qw(is_true);
+
+sub new($$$) {
+	my $pack = shift || die;
+	my $gconfig = shift || die;
+	my $genopts = shift || die;
+	my $file = $ENV{DAHDI_CONF_FILE} || "/etc/dahdi/system.conf";
+	my $self = {
+			FILE	=> $file,
+			GCONFIG	=> $gconfig,
+			GENOPTS	=> $genopts,
+		};
+	bless $self, $pack;
+	return $self;
+}
+
+my $bri_te_last_timing = 1;
+
+sub gen_digital($$) {
+	my $gconfig = shift || die;
+	my $span = shift || die;
+	my $num = $span->num() || die;
+	die "Span #$num is analog" unless $span->is_digital();
+	my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
+	my $timing;
+	my $lbo = 0;
+	my $framing = $span->framing() || die "$0: No framing information for span #$num\n";
+	my $coding =  $span->coding() || die "$0: No coding information for span #$num\n";
+	my $span_crc4 = $span->crc4();
+	$span_crc4 = (defined $span_crc4) ? ",$span_crc4" : '';
+	my $span_yellow = $span->yellow();
+	$span_yellow = (defined $span_yellow) ? ",$span_yellow" : '';
+	# "MFC/R2 does not normally use CRC4"
+	# FIXME: a finer way to override:
+	if ($gconfig->{'pri_connection_type'} eq 'R2') { 
+		$span_crc4 = '';
+		$framing = 'cas';
+	}
+	my $dchan_type = 'dchan';
+	if ($span->is_bri() && is_true($gconfig->{'bri_hardhdlc'})) {
+		$dchan_type = 'hardhdlc';
+	}
+
+	$timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++;
+	printf "span=%d,%d,%d,%s,%s%s%s\n",
+			$num,
+			$timing,
+			$lbo,
+			$framing,
+			$coding,
+			$span_crc4,
+			$span_yellow;
+	printf "# termtype: %s\n", lc($termtype);
+	if ($gconfig->{'pri_connection_type'} eq 'PRI') {
+		printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span);
+		my $dchan = $span->dchan();
+		printf "$dchan_type=%d\n", $dchan->num();
+	} elsif ($gconfig->{'pri_connection_type'} eq 'R2' ) {
+		my $idle_bits = $gconfig->{'r2_idle_bits'};
+		printf "cas=%s:$idle_bits\n", Dahdi::Config::Gen::bchan_range($span);
+		printf "dchan=%d\n", $span->dchan()->num();
+	}
+}
+
+sub gen_signalling($$) {
+	my $gconfig = shift || die;
+	my $chan = shift || die;
+	my $type = $chan->type;
+	my $num = $chan->num;
+
+	die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
+	if($type eq 'EMPTY') {
+		printf "# channel %d, %s, no module.\n", $num, $chan->fqn;
+		return;
+	}
+	my $signalling = $gconfig->{'dahdi_signalling'};
+	my $sig = $signalling->{$type} || die "unknown default dahdi signalling for chan $num type $type";
+	if ($type eq 'IN') {
+		printf "# astbanktype: input\n";
+	} elsif ($type eq 'OUT') {
+		printf "# astbanktype: output\n";
+	}
+	printf "$sig=$num\n";
+}
+
+sub generate($$$) {
+	my $self = shift || die;
+	my $file = $self->{FILE};
+	my $gconfig = $self->{GCONFIG};
+	my $genopts = $self->{GENOPTS};
+	my @spans = @_;
+	warn "Empty configuration -- no spans\n" unless @spans;
+	rename "$file", "$file.bak"
+		or $! == 2	# ENOENT (No dependency on Errno.pm)
+		or die "Failed to backup old config: $!\n";
+	#Dahdi::Config::Gen::show_gconfig($gconfig);
+	print "Generating $file\n" if $genopts->{verbose};
+	open(F, ">$file") || die "$0: Failed to open $file: $!\n";

[... 354 lines stripped ...]



More information about the dahdi-commits mailing list