dahdi-tools/xpp/perl_modules/Dahdi/Config/Gen/System.pm

278 lines
8.2 KiB
Perl

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 print_echo_can($$) {
my $gconfig = shift || die;
my $chans = shift || die; # channel or range of channels.
my $echo_can = $gconfig->{'echo_can'};
return if !defined($echo_can) || $echo_can eq 'none';
print "echocanceller=$echo_can,$chans\n";
}
sub gen_t1_cas($$) {
my $self = shift || die;
my $gconfig = shift || die;
my $parameters = $gconfig->{PARAMETERS} || die;
my $genconf_file = $parameters->{GENCONF_FILE} || die;
my $span = shift || die;
my $num = $span->num() || die;
my $proto = $span->proto || die;
die "Generate configuration for '$proto' is not possible. Maybe you meant R2?"
unless $proto eq 'T1';
my $pri_connection_type = $gconfig->{pri_connection_type} || die;
die "Span #$num is analog" unless $span->is_digital();
die "Span #$num is not CAS" unless $span->is_pri && $pri_connection_type eq 'CAS';
my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
my $timing;
my $lbo = 0;
my $framing = $gconfig->{tdm_framing};
if(!defined $framing) {
$framing = 'esf';
} elsif($framing ne 'esf' && $framing ne 'd4') {
die "T1-CAS valid framing is only 'esf' or 'd4'. Not '$framing'. Check '$genconf_file'\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" : '';
$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);
my $dchan_type;
my $chan_range;
if($span->is_pri()) {
if ($pri_connection_type eq 'PRI') {
$chan_range = Dahdi::Config::Gen::bchan_range($span);
printf "bchan=%s\n", $chan_range;
my $dchan = $span->dchan();
printf "dchan=%d\n", $dchan->num();
} elsif ($pri_connection_type eq 'R2' ) {
my $idle_bits = $gconfig->{'r2_idle_bits'};
$chan_range = Dahdi::Config::Gen::bchan_range($span);
printf "cas=%s:$idle_bits\n", $chan_range;
} elsif ($pri_connection_type eq 'CAS' ) {
my $type = ($termtype eq 'TE') ? 'FXO' : 'FXS';
my $sig = $gconfig->{'dahdi_signalling'}{$type};
my $em_signalling = $gconfig->{'em_signalling'};
if ($em_signalling ne 'none') {
$sig = 'e&m';
# FIXME: but we don't handle E1 yet
$sig = 'e&me1' if $proto eq 'E1';
}
die "unknown default dahdi signalling for chan $num type $type" unless defined $sig;
$chan_range = Dahdi::Config::Gen::chan_range($span->chans());
printf "%s=%s\n", $sig, $chan_range;
}
} else {
die "Digital span $num is not PRI";
}
print_echo_can($gconfig, $chan_range);
}
sub gen_digital($$$) {
my $self = shift || die;
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" : '';
my $span_termination = $span->termination();
$span_termination = (defined $span_termination) ? ",$span_termination" : '';
my $span_softntte = $span->softntte();
$span_softntte = (defined $span_softntte) ? ",$span_softntte" : '';
# "MFC/R2 does not normally use CRC4"
# FIXME: a finer way to override:
if ($gconfig->{'pri_connection_type'} eq 'R2') {
$span_crc4 = '';
$framing = 'cas';
}
$timing = ($termtype eq 'NT') ? 0 : $bri_te_last_timing++;
printf "span=%d,%d,%d,%s,%s%s%s%s%s\n",
$num,
$timing,
$lbo,
$framing,
$coding,
$span_crc4,
$span_yellow,
$span_termination,
$span_softntte;
printf "# termtype: %s\n", lc($termtype);
my $dchan_type;
if ($span->is_bri()) {
my $use_bristuff = 0;
my $cfg_hardhdlc = $gconfig->{'bri_hardhdlc'};
my $xpd = Dahdi::Xpp::xpd_of_span($span);
if(!defined($cfg_hardhdlc) || $cfg_hardhdlc =~ /AUTO/i) {
# Autodetect
if(defined($xpd)) {
# Bristuff?
if(defined($xpd->dchan_hardhdlc) && !is_true($xpd->dchan_hardhdlc)) {
$use_bristuff = 1;
}
}
} elsif(!is_true($cfg_hardhdlc)) {
$use_bristuff = 1;
}
if($use_bristuff) {
$dchan_type = 'dchan';
} else {
$dchan_type = 'hardhdlc';
}
printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span);
my $dchan = $span->dchan();
printf "$dchan_type=%d\n", $dchan->num();
} elsif($span->is_pri()) {
if ($gconfig->{'pri_connection_type'} eq 'PRI') {
printf "bchan=%s\n", Dahdi::Config::Gen::bchan_range($span);
my $dchan = $span->dchan();
printf "dchan=%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();
}
} else {
die "Digital span $num is not BRI, nor PRI?";
}
print_echo_can($gconfig, Dahdi::Config::Gen::bchan_range($span));
}
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";
print_echo_can($gconfig, $num);
}
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";
#$gconfig->dump;
print "Generating $file\n" if $genopts->{verbose};
open(F, ">$file") || die "$0: Failed to open $file: $!\n";
my $old = select F;
printf "# Autogenerated by $0 on %s\n", scalar(localtime);
print "# If you edit this file and execute $0 again,\n";
print "# your manual changes will be LOST.\n";
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) {
if($span->is_pri) {
if($gconfig->{'pri_connection_type'} eq 'CAS') {
$self->gen_t1_cas($gconfig, $span);
} else {
$self->gen_digital($gconfig, $span);
}
} elsif($span->is_bri) {
$self->gen_digital($gconfig, $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_signalling($gconfig, $chan);
}
}
print "\n";
}
print <<"TAIL";
# Global data
loadzone = $gconfig->{'loadzone'}
defaultzone = $gconfig->{'defaultzone'}
TAIL
close F;
select $old;
}
1;
__END__
=head1 NAME
dahdi - Generate configuration for dahdi drivers.
=head1 SYNOPSIS
use Dahdi::Config::Gen::Dahdi;
my $cfg = new Dahdi::Config::Gen::Dahdi(\%global_config, \%genopts);
$cfg->generate(@span_list);
=head1 DESCRIPTION
Generate the F</etc/dahdi/system.conf>.
This is the configuration for dahdi_cfg(1).
Its location may be overriden via the environment variable F<DAHDI_CONF_FILE>.