diff options
Diffstat (limited to 'xpp/xpp_sync')
-rwxr-xr-x | xpp/xpp_sync | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/xpp/xpp_sync b/xpp/xpp_sync new file mode 100755 index 0000000..1438f50 --- /dev/null +++ b/xpp/xpp_sync @@ -0,0 +1,226 @@ +#! /usr/bin/perl -w +# +# Written by Oron Peled <oron@actcom.co.il> +# Copyright (C) 2007, Xorcom +# This program is free software; you can redistribute and/or +# modify it under the same terms as Perl itself. +# +# $Id$ +# +use strict; +use File::Basename; +BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/zconf"); } + +use Zaptel::Xpp; +use Zaptel::Xpp::Xbus; + +my $sync; +my $autoselect; + +sub usage() { + print + "$0: show / set Astribank sync source\n". + "\n". + "Usage: $0 Show sync source.\n". + " $0 <auto|NN|zaptel> Set sync source.\n". + ""; +} + +if(@ARGV == 1) { + if ($ARGV[0] =~ /^(-h|--help|help)$/) { + usage; + exit(0); + } + $sync = shift; + $autoselect = 1 if $sync =~ /^auto$/i; +} + + +sub get_sorted_xpds() { + my @good_xpds; + + foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) { + next unless $xbus->status eq 'CONNECTED'; + foreach my $xpd ($xbus->xpds()) { + my $isreg = $xpd->zt_registration(); + if(!defined($isreg)) { # Failure + printf STDERR "%s: Failed %s\n", $xpd->fqn, $!; + next; + } + next unless $isreg; # Skip unregistered XPDs + push(@good_xpds, $xpd); + } + } + my @pri_nt_xpds = grep { $_->type =~ /(E1|T1|J1)_NT/; } @good_xpds; + my @pri_te_xpds = grep { $_->type =~ /(E1|T1|J1)_TE/; } @good_xpds; + my @bri_nt_xpds = grep { $_->type eq 'BRI_NT'; } @good_xpds; + my @bri_te_xpds = grep { $_->type eq 'BRI_TE'; } @good_xpds; + my @fxo_xpds = grep { $_->type eq 'FXO'; } @good_xpds; + my @fxs_xpds = grep { $_->type eq 'FXS'; } @good_xpds; + + # Sync Priority + return + @pri_nt_xpds, + @bri_nt_xpds, + @fxo_xpds, + @pri_te_xpds, + @bri_te_xpds, + @fxs_xpds; +} + +sub do_select(@) { + my $found; + + foreach my $xpd (@_) { + my $xbus = $xpd->xbus; + my $busnum = $xbus->name; + die "Uknown bus name" unless $busnum; + $busnum =~ s/XBUS-//; + die "bad bus name" unless $busnum =~ /^\d+$/; + #printf "Setting sync: %-10s (%s)\n", $xpd->fqn, $xpd->type; + if(Zaptel::Xpp::sync($busnum)) { + #print "SET $busnum\n"; + $found = 1; + last; + } else { + print STDERR "Failed to set $busnum: $!\n"; + } + } +} + +sub do_set($) { + my $sync = shift; + die "Failed to set sync to '$sync'" unless Zaptel::Xpp::sync($sync); +} + +sub unique_xbus(@) { + my %seen; + + grep { !$seen{$_->xbus}++; } @_; +} + +my $curr_sync = Zaptel::Xpp::sync; +my @sync_xpds = unique_xbus(get_sorted_xpds()); + +sub show_sync() { + foreach my $xpd (@sync_xpds) { + my $xbus = $xpd->xbus; + my $xpdstr = '[ ' . $xbus->pretty_xpds . ' ]'; + my $label = '[' . $xbus->label() . ']'; + my $connector = '(' . $xbus->connector . ')'; + my $mark = ($curr_sync =~ /\d+/ and $xbus->num == $curr_sync)?"+":""; + my $padding = ' ' x (40 - length $xpdstr); + printf " %1s %s %-25s %-14s %s\n", $mark, $xbus->name, $connector, $label, $xpdstr; + } +} + +sub check_fxo_host_sync() { + my @host_synced_xpds = grep { $_->xbus->num() ne $curr_sync } @sync_xpds; + my @host_synced_fxos = grep($_->type eq 'FXO', @host_synced_xpds); + if(@host_synced_fxos) { + my @bad_xbus = map { $_->xbus } unique_xbus(@host_synced_fxos); + our $lines = join("\n\t", map { $_->name } @bad_xbus); + print STDERR <<"END"; +================================================== +WARNING: FXO which is not the syncer cause bad PCM + Affected Astribanks are: +-------------------------------------------------- + $lines +================================================== +END + } +} + +if($sync) { + if($autoselect) { + do_select(@sync_xpds); + } else { + $sync = uc($sync); + do_set($sync); + } + $curr_sync = Zaptel::Xpp::sync; + #print "New sync: ", Zaptel::Xpp::sync, "\n"; +} else { + print "Current sync: ", $curr_sync, "\n"; + print "Best Available Syncers:\n"; + show_sync; + check_fxo_host_sync; +} + +__END__ + +=head1 NAME + +xpp_sync - Handle sync selection of Xorcom Astribanks. + +=head1 SYNOPSIS + +xpp_sync [auto|zaptel|nn] + +=head1 DESCRIPTION + +On a normal operation one Astribank device provides timing for all the +other Astribank devices. + +When run without parameters, xpp_sync will display a list of Astribanks +(xbuses) that are connected and registered as Zaptel spans. The current +xpp sync master will be marked. + +If you this an Astribank is connected and yet it does not appear on the +output of xpp_sync, it may be unregistered. Try running zt_registration . + +=head2 Parameters + +=over + +=item auto + +Automatically selects the best Astribank for syncing. + +=item zaptel + +Gets synchronization from the Zaptel sync master. + +=item nn + +Sets XBUS-I<nn> as sync source. + +=back + +(Parameter name is case-insensitive) + +=head2 Example output: + + Setting SYNC + Current sync: 01 + Best Available Syncers: + + XBUS-01 (usb-0000:00:10.4-3) [usb:12345678] [ PRI_TE PRI_NT PRI_TE PRI_NT ] + XBUS-00 (usb-0000:00:10.4-2) [usb:QA-01] [ FXS FXO ] + ================================================== + WARNING: FXO which is not the syncer cause bad PCM + Affected Astribanks are: + -------------------------------------------------- + XBUS-00 + ================================================== + +In this example we see that the recommended xpp sync master is XBUS-02 - +it is the first on the list. It is also the actual syncer, as we can see +from the '+' beside it. + +xpp_sync is normally called from both the zaptel init.d script and the +the Astribank udev script. The parameter it is called with defaults to +I<auto>, but it is possible to override that parameter (e.g: set it to +I<zaptel>) through the value of XPP_SYNC in either /etc/defualt/zaptel +or /etc/sysconfig/zaptel . + +=head1 FILES + +=over + +=item /proc/xpp/sync + +xpp_sync is essentially a nicer interface to /proc/xpp/sync . That file +shows the current xpp sync master (and in what format you need to write +to it to set the master). + +=back |