summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2009-11-04 17:52:29 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2009-11-04 17:52:29 +0000
commitef4399ff222f532ef427255e30ec9016b9e25c1e (patch)
treec607bf7c25e13ca4d312552f3bac3c980f205faa
parent1588ee041e01dc31a75046dcf442da2fdc68ed66 (diff)
CAS DAHD/Asterisk configuration generation support
Also support generating (open)R2 config in chan_dahdi.conf, while we're at it. Default configuration remains ISDN as before if no extra settings are given in genconf_parameters. Merged revisions 7016,7018-7019,7224,7257 via svnmerge from http://svn.digium.com/svn/dahdi/tools/trunk ........ r7016 | tzafrir | 2009-08-16 20:04:04 +0300 (Sun, 16 Aug 2009) | 6 lines dahdi-perl: chan_dahdi.conf generator can generate openr2 conf If configured to use R2 ("pri_connection_type R2" in genconf_parameters), the chandahdi generator of dahdi_genconf will now generate configuration for the openr2 support in chan_dahdi. ........ r7018 | tzafrir | 2009-08-16 20:19:26 +0300 (Sun, 16 Aug 2009) | 10 lines xpp: Dahdi::Config::Gen.pm: improvements in preperation for T1-CAS: - New channo_range() method which returns range strings for any list of channel numbers (handle sorting, validation, etc.) - Reimplement bchan_range() as a small wrapper around channo_range(). - Another small wrapper is chan_range() that works on channel objects. - Also a parse_chan_range() does the reverse (from range string to a list of channel numbers). This isn't used at the moment. xpp rev: 7306 ........ r7019 | tzafrir | 2009-08-16 20:27:28 +0300 (Sun, 16 Aug 2009) | 11 lines dahdi-perl: Add basic T1-CAS support for dahdi_genconf - Support added in generators of system.conf and of chan_dahdi.conf . - Some strange asumptions about being FXS/FXO depending on being timing provider/supplier. - New gen_cas() method for Chandahdi and System. - Now gen_digital() is a bit cleaner. - Call gen_cas(), gen_openr2(), gen_digital() according to the 'pri_connection_type' config (CAS, R2, PRI/BRI). xpp rev: 7307 ........ r7224 | tzafrir | 2009-09-27 17:01:20 +0200 (Sun, 27 Sep 2009) | 6 lines dahdi_perl: improved config generation for T1 CAS A few extra options for a CAS span signalling. xpp rev: 7343, 7346, 7369 ........ r7257 | tzafrir | 2009-09-29 21:28:58 +0200 (Tue, 29 Sep 2009) | 2 lines xpp: more T1-CAS config generation support ........ git-svn-id: http://svn.asterisk.org/svn/dahdi/tools/branches/2.2@7475 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--xpp/genconf_parameters19
-rw-r--r--xpp/perl_modules/Dahdi/Config/Gen.pm78
-rw-r--r--xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm94
-rw-r--r--xpp/perl_modules/Dahdi/Config/Gen/System.pm84
-rw-r--r--xpp/perl_modules/Dahdi/Config/Params.pm2
5 files changed, 258 insertions, 19 deletions
diff --git a/xpp/genconf_parameters b/xpp/genconf_parameters
index 3a4b2fc..e48e2b8 100644
--- a/xpp/genconf_parameters
+++ b/xpp/genconf_parameters
@@ -107,8 +107,25 @@
# chan_dahdi.conf . The meaning of this may be extended somehow to support
# R2 through openr2/chan_dahdi later on.
#pri_connection_type R2
+#pri_connection_type CAS
+#
+# Explicitly set the idle bits for E1 CAS (Sample value is the default):
#r2_idle_bits 1101
-
+#
+# Set T1 framing type to d4 instead of esf:
+#tdm_framing d4
+#
+# Use E&M on CAS (default is FXS/FXO). If set, E1 spans will be used as
+# E&M-E1 and T1 will use the requested type:
+#em_signalling em
+#em_signalling em_w
+#em_signalling featd
+#em_signalling featdtmf
+#em_signalling featdtmf_ta
+#em_signalling featb
+#em_signalling fgccama
+#em_signalling fgccamamf
+#
# pri_termtype contains a list of settings:
# Currently the only setting is for TE or NT (the default is TE). This
# sets two different but normally related configuration items:
diff --git a/xpp/perl_modules/Dahdi/Config/Gen.pm b/xpp/perl_modules/Dahdi/Config/Gen.pm
index 709fad7..5cfeb9c 100644
--- a/xpp/perl_modules/Dahdi/Config/Gen.pm
+++ b/xpp/perl_modules/Dahdi/Config/Gen.pm
@@ -55,33 +55,89 @@ sub is_true($) {
return $val =~ /^(1|y|yes)$/i;
}
-# Generate channel range strings from span objects
+sub range_string($$) {
+ my ($start, $end) = @_;
+
+ if($start == $end) {
+ sprintf "%d", $start;
+ } else {
+ sprintf "%d-%d", $start, $end;
+ }
+}
+
+# Generate channel range strings from arrays of chan numbers
# E.g: "63-77,79-93"
-sub bchan_range($) {
- my $span = shift || die;
- my $first_chan = ($span->chans())[0];
- my $first_num = $first_chan->num();
+sub channo_range(@) {
+ my @channos = sort { $a <=> $b } @_;
+ my $first_num = $channos[0];
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;
+ foreach my $c (@channos) {
+ my $curr = $c;
if(!defined($prev)) {
+ # First iteration
$prev = $curr;
} elsif($curr != $prev + 1) {
- push(@range, sprintf("%d-%d", $range_start, $prev));
+ # New range
+ push(@range, range_string($range_start, $prev));
$range_start = $curr;
}
$prev = $curr;
}
if($prev >= $first_num) {
- push(@range, sprintf("%d-%d", $range_start, $prev));
+ # Last range
+ push(@range, range_string($range_start, $prev));
}
return join(',', @range);
}
+# Generate channel range strings from chan objects
+# E.g: "63-77,79-93"
+sub chan_range(@) {
+ my @chans = sort { $a->num <=> $b->num } @_;
+ my @channos = map { $_->num } @chans;
+ channo_range(@channos);
+}
+
+# Generate channel range strings from digital span objects
+# E.g: "63-77,79-93"
+sub bchan_range($) {
+ my $span = shift || die;
+ die unless $span->is_digital();
+ my $first_chan = ($span->chans())[0];
+ my $first_num = $first_chan->num();
+ my $bchan_ref = $span->bchan_list();
+ my @channos = map { $_ + $first_num } @{$bchan_ref};
+ channo_range(@channos);
+}
+
+# Returns a channel numbers array from a channel range string
+sub parse_chan_range($) {
+ my $rangestr = shift;
+ $rangestr =~ s/\s*//g; # Squeeze
+ die "Bad characters in '$rangestr'" if $rangestr =~ /[^\d\s,-]/;
+ my @ranges = split(/,/, $rangestr);
+ my @channos;
+ my $last_end;
+
+ foreach my $range (@ranges) {
+ my ($start, $end) = split(/-/, $range, 2);
+ $end = $start unless defined $end;
+ die "Bad characters in '$start'" if $start =~ /\D/;
+ die "Bad characters in '$end'" if $end =~ /\D/;
+ die "Reversed range $end < $start" if $end < $start;
+ die "Channel number < 1" if $start < 1;
+ die "New range begins below previous $start <= $last_end" if defined($last_end) && $last_end >= $start;
+ for(my $i = $start + 0; $i <= $end; $i++) {
+ push(@channos, $i);
+ }
+ $last_end = $end;
+ }
+ return sort { $a <=> $b } @channos;
+}
+
sub new($) {
my $pack = shift || die "$0: Missing package argument";
my $p = shift || die "$0: Missing parameters argument";
@@ -149,10 +205,12 @@ sub new($) {
bri_hardhdlc
bri_sig_style
r2_idle_bits
+ tdm_framing
echo_can
brint_overlap
pri_termtype
pri_connection_type
+ em_signalling
);
foreach my $k (@trivial) {
$gconfig->{$k} = $p->item($k);
diff --git a/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
index 8845544..613566a 100644
--- a/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
+++ b/xpp/perl_modules/Dahdi/Config/Gen/Chandahdi.pm
@@ -38,10 +38,83 @@ sub reset_chandahdi_values {
}
}
-sub gen_digital($$) {
+sub gen_openr2($$$) {
my $self = shift || die;
+ my $gconfig = shift || die;
+ my $span = shift || die;
+ my $num = $span->num() || die;
+ my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
+ my $type = $span->type;
+ # Fake type for signalling
+ my $faketype = ($termtype eq 'TE') ? 'FXO' : 'FXS';
+ my $group = $gconfig->{'group'}{"$type"};
+ die "$0: missing default group (termtype=$termtype)\n" unless defined($group);
+ my $context = $gconfig->{'context'}{"$faketype"};
+ die "$0: missing default context\n" unless $context;
+ my @to_reset = qw/context group/;
+ my $chans = Dahdi::Config::Gen::bchan_range($span);
+ $group .= "," . (10 + $num); # Invent unique group per span
+ my $country = $gconfig->{'loadzone'};
+ my @valid_countries = qw( ar br cn cz co ec itu mx ph ve );
+ die "Country '$country' is invalid for R2. Use one of: @valid_countries\n"
+ unless grep { $_ eq $country } @valid_countries;
+ printf "group=$group\n";
+ printf "context=$context\n";
+ printf "switchtype = %s\n", $span->switchtype;
+ printf "signalling = %s\n", 'mfcr2';
+ printf "caller = %s\n", ($termtype eq 'TE') ? 'no' : 'yes';
+ printf "mfcr2_logdir = span%d\n", $span->num;
+ print <<"EOF";
+mfcr2_variant=$country
+mfcr2_get_ani_first=no
+mfcr2_max_ani=10
+mfcr2_max_dnis=4
+mfcr2_category=national_subscriber
+mfcr2_call_files=yes
+mfcr2_logging=all
+mfcr2_mfback_timeout=-1
+mfcr2_metering_pulse_timeout=-1
+EOF
+ printf "channel => %s\n", $chans;
+
+ reset_chandahdi_values(@to_reset);
+}
+
+sub gen_cas($$$) {
+ my $self = shift || die;
+ my $gconfig = shift || die;
+ my $span = shift || die;
+ my $num = $span->num() || die;
+ my $termtype = $span->termtype() || die "$0: Span #$num -- unkown termtype [NT/TE]\n";
+ my $type = $span->type;
+ my $group = $gconfig->{'group'}{"$type"};
+ die "$0: missing default group (termtype=$termtype)\n" unless defined($group);
+ my $context = $gconfig->{'context'}{"$type"};
+ die "$0: missing default context\n" unless $context;
+ # Fake type for signalling
+ my $faketype = ($termtype eq 'TE') ? 'FXO' : 'FXS';
+ my $sig = $gconfig->{'chan_dahdi_signalling'}{$faketype};
+ my $em_signalling = $gconfig->{'em_signalling'};
+ if ($em_signalling ne 'none') {
+ $sig = $em_signalling;
+ # FIXME: but we don't handle E1 yet
+ $sig = 'em_e1' if $span->proto eq 'E1';
+ }
+ my @to_reset = qw/context group/;
+ my $chans = Dahdi::Config::Gen::chan_range($span->chans());
+ $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", $chans;
+ reset_chandahdi_values(@to_reset);
+}
+
+sub gen_digital($$$) {
+ my $self = shift || die;
+ my $gconfig = 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') {
@@ -66,7 +139,7 @@ sub gen_digital($$) {
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";
@@ -92,6 +165,7 @@ sub gen_channel($$) {
return if $type eq 'EMPTY';
die "missing default_chan_dahdi_signalling for chan #$num type $type" unless $sig;
+ die "missing context for chan #$num type $type" unless $context;
$callerid = ($type eq 'FXO')
? 'asreceived'
: sprintf "\"Channel %d\" <%04d>", $num, $exten;
@@ -153,8 +227,18 @@ sub generate($) {
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);
+ if($span->is_digital) {
+ if($span->is_pri) {
+ if($gconfig->{'pri_connection_type'} eq 'R2') {
+ $self->gen_openr2($gconfig, $span);
+ } elsif($gconfig->{'pri_connection_type'} eq 'CAS') {
+ $self->gen_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(is_true($genopts->{'freepbx'}) || is_true($gconfig->{'freepbx'})) {
diff --git a/xpp/perl_modules/Dahdi/Config/Gen/System.pm b/xpp/perl_modules/Dahdi/Config/Gen/System.pm
index 3f9217b..d1dfe40 100644
--- a/xpp/perl_modules/Dahdi/Config/Gen/System.pm
+++ b/xpp/perl_modules/Dahdi/Config/Gen/System.pm
@@ -28,7 +28,77 @@ sub print_echo_can($$) {
print "echocanceller=$echo_can,$chans\n";
}
-sub gen_digital($$) {
+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;
+ printf "dchan=%d\n", $span->dchan()->num();
+ } 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;
@@ -145,8 +215,16 @@ sub generate($$$) {
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);
+ 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) {
diff --git a/xpp/perl_modules/Dahdi/Config/Params.pm b/xpp/perl_modules/Dahdi/Config/Params.pm
index 816b5c1..0b00caa 100644
--- a/xpp/perl_modules/Dahdi/Config/Params.pm
+++ b/xpp/perl_modules/Dahdi/Config/Params.pm
@@ -96,6 +96,7 @@ sub item($$) {
fxs_immediate => 'no',
fxs_default_start => 'ks',
fxo_default_start => 'ks',
+ em_signalling => 'none',
lc_country => 'us',
context_lines => 'from-pstn',
context_phones => 'from-internal',
@@ -109,6 +110,7 @@ sub item($$) {
bri_hardhdlc => 'auto',
pri_connection_type => 'PRI',
r2_idle_bits => '1101',
+ tdm_framing => 'esf',
'pri_termtype' => [ 'SPAN/* TE' ],
);