package Zaptel::Config::Gen::Zaptel; use strict; use Zaptel::Config::Gen qw(is_true); sub new($$$) { my $pack = shift || die; my $gconfig = shift || die; my $genopts = shift || die; my $file = $ENV{ZAPCONF_FILE} || "/etc/zaptel.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", Zaptel::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", Zaptel::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->{'zaptel_signalling'}; my $sig = $signalling->{$type} || die "unknown default zaptel 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"; #$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 %s on %s -- do not hand edit\n", $0, scalar(localtime); print <<"HEAD"; # Zaptel Configuration File # # This file is parsed by the Zaptel Configurator, ztcfg # HEAD foreach my $span (@spans) { printf "# Span %d: %s %s\n", $span->num, $span->name, $span->description; if($span->is_digital()) { 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 zaptel - Generate configuration for zaptel drivers. =head1 SYNOPSIS use Zaptel::Config::Gen::Zaptel; my $cfg = new Zaptel::Config::Gen::Zaptel(\%global_config, \%genopts); $cfg->generate(@span_list); =head1 DESCRIPTION Generate the F. This is the configuration for ztcfg(1). Its location may be overriden via the environment variable F.